ChargeBeep
A 150 KB Mac menu bar app that plays a sound when your battery reaches the charge level you pick. Plain Swift, no Electron, no network code.
- Swift
- AppKit
- IOKit
- IOPowerSources
Why it exists
My MacBook used to sit at 100% charge all day, which is the worst thing you can do to a lithium battery. ChargeBeep is a tiny menu bar app that fixes this: you pick a charge level, plug in, and walk away — the moment the battery hits your target, it plays a sound. It also shows the exact battery percentage in the menu bar, which macOS hides by default.
The whole app is a single ~730-line Swift file, no storyboards, no package manager,
no dependencies. It compiles with one swiftc -O invocation into a ~150 KB binary.
Event-driven, not polled
The first version polled the battery every 30 seconds. It worked, but it was the
wrong design — too slow for an instant alert, and wasteful at shorter intervals.
The system already knows when power changes, so the final version subscribes to
IOPSNotificationCreateRunLoopSource and adds it to the main run loop. That callback
fires the instant you plug in, unplug, or the percentage ticks — reaction is immediate
and the app is idle the rest of the time. A one-minute Timer stays as a
belt-and-suspenders fallback, plus a didWakeNotification observer to re-check
immediately after the Mac wakes from sleep.
Battery values come from IOPSCopyPowerSourcesInfo / IOPSGetPowerSourceDescription
rather than shelling out to pmset and parsing text — I read kIOPSCurrentCapacityKey
and kIOPSMaxCapacityKey off the internal-battery power source and compute the
percentage directly. No string parsing, no subprocess per tick.
Keeping the Mac awake without breaking sleep
Keeping the Mac awake while charging was the tricky part. The obvious approach —
sudo pmset disablesleep 1 — needs a password and, worse, leaves system sleep
permanently disabled if the app ever crashes before it can undo it. That’s a
terrible thing to ship.
The right tool is an IOKit power assertion: IOPMAssertionCreateWithName with
kIOPMAssertionTypePreventUserIdleSystemSleep. It needs no privileges, works with the
lid open, and — critically — the kernel releases it automatically when the process
dies. Sleep can never get stuck. The assertion is created only while actively charging
below the threshold and released the moment the target is hit, so the Mac goes back to
normal power behavior as soon as its job is done.
There’s an optional “powerful mode” for keeping the Mac awake with the lid closed,
which genuinely does require pmset disablesleep. Instead of asking for a password
every time, ChargeBeep installs a single narrowly-scoped sudoers.d rule — NOPASSWD
for exactly /usr/bin/pmset disablesleep * and nothing else — via one admin prompt,
and removes that file cleanly when the mode is turned off or the app is uninstalled.
The one-shot “armed” pattern
Playing the sound exactly once per charge cycle is deceptively fiddly: the power
callback can fire many times around the threshold. I use a small armed boolean — it’s
set true while plugged in and below target, and the beep only fires on the
below→reached transition, then disarms. Unplugging re-arms it. It’s a tiny state
machine, but it’s the difference between one polite chime and your laptop beeping at
you every few seconds.
Built small on purpose
- Plain Swift and AppKit — no Electron, no SwiftPM, no third-party code
- ~150 KB binary from a single
main.swift - No network code at all: nothing is tracked, nothing phones home
- Autostart via a LaunchAgent plist written on first run (works on macOS 11+, no deprecated login-item APIs)
- Ships as a drag-to-Applications
.dmgbuilt by a ~60-line bash script - Sound picker auto-discovers bundled, system, and user-provided audio files