What is my battery's true health, and how much power is it really using?
Website: whatbattery.app (overview, screenshots, and Pro details)
A small macOS menu bar app that shows the real health of your battery, the live power going in and out, which apps are using it, and the service condition macOS uses, for your Mac and any iPhone or iPad you connect to it.
System Settings rounds battery health to a whole number and hides almost everything else. WhatBattery reads the same data Apple does, straight from IOKit and the SMC, and shows you the real maximum capacity, the cycle count, the live watts in and out, the temperature, and whether the battery actually needs service. No rounding, no guessing.
Everything below is free unless it's marked (Pro). The full Pro list is in its own section; Pro is a one-time licence.
For your Mac, in the menu bar dropdown and the main window:
- True battery health: health to one decimal and the cycle count, computed from the raw mAh figures (
NominalChargeCapacity / DesignCapacity) rather than the whole number macOS shows, so a worn battery can't hide as "100%". The percentage and the cycle count are free. The underlying mAh capacities are a Pro line in the app (the CLI prints them either way). - Live power: watts in and out in real time, taken from the SMC power rail rather than the stale fuel-gauge reading, plus the charger your Mac negotiated, the voltage, and the temperature.
- Service condition: the same Normal / Service Recommended / Service Battery verdict macOS uses, read from the system so it matches System Settings. macOS's own "Maximum Capacity" percentage is shown alongside WhatBattery's unrounded figure whenever the two differ, so you can see why rather than wonder which to believe: ours is the gauge's raw estimate, Apple's is rounded and smoothed.
- Device detail: marketing model name ("MacBook Pro (14-inch, M5)"), model identifier, regulatory model number, chip, serial, and Low Power Mode status, alongside the battery serial and adapter.
- What's using power (Pro): the Apps tab ranks your apps by live watts, from the same kernel energy counters behind Activity Monitor's Energy tab but in real units instead of a unitless score, plus the top power users over the last day, week, or month. Honest framing: the display, radios, and system processes aren't attributable per app, so the figures are never dressed up as a share of the battery.
For a connected iPhone or iPad (Pro):
- The same health, cycle count, charge, temperature, voltage, and live power, read straight from the device over a cable or Wi-Fi, with no app installed on the device. It uses the same battery node and the same health math as the Mac.
For your Bluetooth accessories:
- The live battery level of a connected keyboard, mouse, trackpad, or AirPods, in the dropdown and the Accessories tab. AirPods are broken out per bud and case (L / R / Case). Devices that only publish battery over Bluetooth Low Energy, like Logitech's MX mice, are read over the GATT Battery Service, matching what System Settings sees. A few devices publish nothing at all, and those show "Battery unavailable" rather than a guess. This is free.
- Devices appear the moment they connect and leave when they disconnect, no waiting on a poll.
Click the gear icon in the dropdown to open Settings, where you can enter a Pro licence key and configure threshold notifications.
WhatBattery is free and open source. The free app shows battery health, live power, and the service condition for your Mac. WhatBattery Pro unlocks the long-term and multi-device features:
- Lifetime Analyzer: a live history of charge, temperature, voltage, and power, with charts and min/avg/max stats over a selectable range.
- iPhone and iPad battery: read the health and cycle count of a connected device straight from your Mac, over USB or Wi-Fi.
- Battery Health History: a long-term, per-device record of monthly health and cycles, for your Mac and every device you connect, kept for years, with backup and restore.
- Battery runway: a forecast, not just today's number. The wear rate ("down 4% over the last 90 days"), the window in which your battery is projected to reach 80% health, and a flag when it starts ageing faster than its own trend. Built from the long-term health history, Macs first. No other battery app projects forward. It also knows when not to: the health reading is the fuel gauge's own revisable estimate, which steps when the gauge recalibrates, so a few weeks of readings can imply a steep decline that is not real. WhatBattery tests whether the trend is statistically distinguishable from that noise, and stays quiet when it is not.
- Cells and internals: the per-cell data the gauge keeps and macOS never shows. Each cell's voltage, learned capacity and resistance, how far apart they are drifting (a failing pack shows one cell pulling away long before the health figure moves), the cycle count at the gauge's last recalibration, and lifetime temperature, voltage and current extremes going back before you installed the app.
- Charging sessions: every charge recorded with how fast it ran, how hot it got, and a charger verdict ("58W of 96W"). A charger is flagged as underpowered when what it advertises falls clearly below what your Mac can fast-charge at; the judgement is on the charger's own claim, never on how fast a session happened to run, so a good charger loafing through an overnight charge is never wrongly accused.
- What's using power: apps ranked by live watts, plus the recorded top power users over the last day, week, or month.
- Charging habits: thirty days of your charging behaviour summarised, with a pointer when a habit warrants Optimized Charging or a charge limiter. WhatBattery only observes; it never changes how your Mac charges.
- Reports and export: a one-page battery report as PDF or print, and CSV / JSON export of your logged history, for warranty claims, resale, or your own records.
- Threshold notifications: alerts for charge high/low, temperature, and health milestones.
- Smart alerts: the wear-driven ones too: sat plugged in at 100% for hours, no full charge cycle in a long while, health dropping faster than the battery's own trend, and running warm while charging.
- Anonymous wear comparison (opt-in): see where your battery's health sits among other readings of the same model and cycle band. One anonymous reading a week: model identifier, cycle count rounded to the hundred below, health percent, and a coarse age figure. No serial, no device name, no OS version, nothing tied to your licence, and contributions age out after 13 months.
- Accessory forecast and alerts: a per-device level history for your keyboard, mouse, trackpad, and AirPods, with a runtime forecast from the real discharge trend: how long until it dies ("about 3 days left", listening time for AirPods) and roughly how long a full charge lasts. The low-battery alert fires before the accessory dies and says how long is left, and you can show an accessory's level right in the menu bar.
One-time purchase, works on up to 2 Macs. See whatbattery.app for details.
Visit whatbattery.app for an overview and screenshots, or install directly below.
Download the latest WhatBattery.zip from the Releases page, unzip, and drag WhatBattery.app to /Applications.
The app is signed with a Developer ID and notarised by Apple, so there are no Gatekeeper warnings.
It's not on the Mac App Store on purpose: App Sandbox blocks the low-level IOKit and SMC reads WhatBattery depends on, and reading a connected iPhone or iPad uses a private framework that the store doesn't allow, so it ships signed and notarised outside the store instead.
Requires macOS 14 (Sonoma) or later, Apple Silicon only. Intel support is feasible later (AppleSmartBattery and the SMC exist on Intel too) but is out of scope for now.
Note: the manual install gives you the menu bar app. A
whatbatteryCLI is bundled inside the.appatWhatBattery.app/Contents/Helpers/whatbatteryand is not on your PATH by default. Install via Homebrew to get the CLI set up automatically, or symlink it yourself (see below).
brew install --cask darrylmorley/whatbattery/whatbatteryThis installs the menu bar app and symlinks the whatbattery CLI into your PATH.
A whatbattery binary ships alongside the menu bar app, driven by the same reader:
$ whatbattery
Model MacBook Pro (14-inch, M5)
Health 99.6% (6,225 / 6,249 mAh)
Charge 100%, fully charged
Cycles 42 (design 1000)
Temperature 30.4°C
Power 0.0 W (100W pd charger)
Voltage 13.21 V
Flags:
whatbattery # human-readable battery summary
whatbattery --json # structured JSON, pipe into jq
whatbattery --watch # live, refreshes as values change (Ctrl+C to exit)
whatbattery --idevice # read a connected iPhone / iPad's battery (Pro)
whatbattery --accessories # Bluetooth accessory battery levels (keyboard, mouse, AirPods)
whatbattery --version
whatbattery --helpPro from the command line:
whatbattery --report # Pro: one-page battery report (current + lifetime + runway forecast)
whatbattery --charging # Pro: latest charger verdict and recent charges
whatbattery --export csv --range month # Pro: export logged history (csv|json, week|month|year|all)
whatbattery --activate XXXX-XXXX-XXXX-XXXX # validate and store a Pro licence
whatbattery --licence # show current licence status
whatbattery --deactivate # remove the stored licence
whatbattery --pro # show Pro features, open purchase pageIf you installed the .app manually rather than via Homebrew, symlink the CLI into your PATH:
ln -s /Applications/WhatBattery.app/Contents/Helpers/whatbattery /usr/local/bin/whatbatteryWhatBattery reads from Apple's own interfaces. No entitlements, no kernel extension, no helper daemon, and it never writes to the battery or changes charging behaviour:
| Source | What it gives us |
|---|---|
AppleSmartBattery (IOKit) |
Raw charge capacity, design capacity, cycle count, voltage, temperature, and adapter info. Health is computed from NominalChargeCapacity / DesignCapacity (on Apple Silicon MaxCapacity is a pinned percentage, so it is never used). |
AppleSmartBattery → BatteryData / LifetimeData (IOKit) |
The nested dictionary the gauge keeps and macOS never surfaces: per-cell voltage, learned capacity (Qmax) and resistance, the cycle count at the last recalibration, and lifetime temperature, voltage and current extremes covering the pack's whole life. Feeds the Pro "Cells and internals" card. |
| SMC power rails | Live power in and out: PPBR for the live battery rail (the fuel-gauge BatteryPower sits stale on Apple Silicon), VD0R / ID0R / PDTR for DC-in. Read-only; degrades to nil if the SMC open is refused. |
system_profiler SPPowerDataType |
The battery "Condition" line, which matches System Settings, and the Maximum Capacity percentage, shown beside WhatBattery's unrounded figure whenever the two differ. The IOPowerSources BatteryHealth key is not used: it reported "Check Battery" on a healthy battery, so it is unreliable. |
IODeviceTree / IOPlatformExpertDevice / sysctl |
Marketing model name, regulatory model number, model identifier, chip, and serial. |
MobileDevice.framework diagnostics relay |
For a connected iPhone or iPad, the device's AppleSmartBattery node over the lockdown relay (the same path Finder and Xcode use), mapped through the same health math as the Mac. |
Bluetooth (IORegistry BatteryPercent + system_profiler SPBluetoothDataType) |
Battery levels for connected Bluetooth accessories (keyboard, mouse, trackpad, AirPods). macOS asks for Bluetooth access the first time you open the Accessories tab; it is used only to read these levels locally. |
| GATT Battery Service (CoreBluetooth) | Levels for accessories that only publish battery over Bluetooth Low Energy (Logitech MX mice and the like). One bounded read per refresh of already-connected devices: no scanning, no pairing, and it never prompts (it only runs once Bluetooth access is already granted). |
Per-process energy counters (libproc) |
The Apps tab's watts: the cumulative energy the kernel bills to each of your processes, diffed between passes. Your own processes only; system daemons refuse the unprivileged read. |
swift build # compile everything
swift run WhatBattery # run the menu bar app (dev mode, no widget or bundle structure)
swift run whatbattery-cli # run the CLI
swift test # run the test suiteRequires Swift 5.9+ (Xcode 15+). swift run WhatBattery launches a working dev build, but without the widget extension or a proper .app bundle. For a distributable build, use the scripts below.
./scripts/smoke-test.shBuilds, assembles a real WhatBattery.app (menu bar binary + CLI in Helpers/ + embedded widget), signs, notarises (if configured), and runs an alive-after-2s check plus CLI --version / --json checks. Produces dist/WhatBattery.app. A real bundle is required for the menu bar app and notifications.
Modes:
| Configuration | Result |
|---|---|
No .env |
Ad-hoc signed. Works locally; Gatekeeper warns on other Macs. |
.env with DEVELOPER_ID |
Developer ID signed + hardened runtime. |
.env with DEVELOPER_ID + NOTARY_PROFILE |
Full notarisation + stapled ticket. Gatekeeper-clean for everyone. |
Cutting a release:
# write release-notes/v<version>.md first, then:
./scripts/release.sh <version>The wrapper runs the whole pipeline: bumps the version, builds, signs, notarises, smoke-tests, bumps the local cask, tags and pushes, creates the GitHub release, verifies the uploaded asset's sha, and updates the Homebrew tap. Use --dry-run first. Requires gh (auth'd) and the env vars from .env.example.
- Apple Silicon only, for now. WhatBattery targets M1 and later on macOS 14+. Intel is feasible later but unsupported today.
- Reading an iPhone or iPad needs a one-time trust. Connect the device with a cable and tap Trust once; after that it can be read over USB or Wi-Fi. The diagnostics relay it uses is a private, undocumented interface whose keys can change between iOS versions, so WhatBattery validates the data it reads and shows a "battery not readable" state rather than bogus numbers if a future iOS changes the fields.
- No genuine / counterfeit verdict. There is no public signal that reliably distinguishes a genuine battery on a genuine machine, so WhatBattery shows the trustworthy service condition instead of guessing.
- Pack manufacturer and manufacture date are not shown. macOS itself exposes neither cleanly, and the raw blobs don't map to a value we can trust, so they're left out rather than shown wrong.
WhatBattery reads battery and power data locally from your Mac (and from a connected iPhone or iPad over the cable or Wi-Fi). None of it is sent anywhere automatically.
- No analytics, no telemetry. The app reads local battery data and nothing else.
- Bluetooth: macOS asks for Bluetooth access the first time you open the Accessories tab. It is used only to read the battery level of your connected accessories, locally. Nothing is sent anywhere, and the rest of the app works without it.
- Licence check: the only network request is a one-time licence validation when you activate Pro.
- Update checks: WhatBattery checks the GitHub Releases API for a newer version. No personal data or hardware info is included.
Issues and PRs welcome. The code is small and tries to stay readable.
| Module | Role |
|---|---|
Sources/WhatBattery/ |
Menu bar app UI (SwiftUI dropdown, main window, settings pane) |
Sources/WhatBatteryCore/ |
Pure Swift: battery models, health math, and formatters. No IOKit. |
Sources/WhatBatteryDarwinBackend/ |
All IOKit / SMC: AppleSmartBattery reader, SMC power reader, system info, iDevice bridge |
Sources/WhatBatteryAppKit/ |
Plugin registry and extension points (hooks for Pro features, CLI commands, menu items) |
Sources/WhatBatteryWidget/ |
WidgetKit extension (desktop widget) |
Sources/WhatBatteryCLI/ |
CLI binary, shares Core / Backend with the app |
Built by Darryl Morley, maker of WhatCable and WhatPort.
The AppleSmartBattery and SMC readers are focused copies of the battery code already shipping in WhatCable.


