A tiny macOS menu bar app that warns you when the battery runs low.
- Shows a warning panel when the charge drops to or below your threshold while on battery.
- The panel is drawn by the app itself, not by Notification Center: it needs no permission and it never disappears on its own.
- It closes on three things only: you press Dismiss, you plug in the charger, or the charge climbs back above the threshold.
- No polling: it listens to IOKit power-source events, so it sits at ~0% CPU.
- No Dock icon, no window — just a battery icon in the menu bar.
Requires macOS 13 or later. Universal: Apple Silicon and Intel.
Download BatteryNotify.dmg from the
latest release, open it and drag the app into
Applications.
The app is signed ad-hoc rather than with an Apple Developer ID, so macOS blocks the first launch with "Apple could not verify BatteryNotify is free of malware". Press Done there — not Move to Trash — then let it through in one of two ways:
System Settings -> Privacy & Security, scroll down to the notice about the blocked app and press Open Anyway, or
drop the download flag from a terminal:
xattr -d com.apple.quarantine /Applications/BatteryNotify.app
macOS remembers the decision, so every later launch is normal. Control-clicking the app and choosing Open used to work as a shortcut; macOS 15 removed it.
Click the menu bar icon:
- current percentage and power source
- threshold picker: 10% / 15% / 20% / 25% / 30% (default 20%)
- Launch at Login toggle
- Quit
Launch at Login uses SMAppService, which expects the app to live in a stable
location, so register it from /Applications rather than from a build folder.
Xcode is not required, only the Command Line Tools.
./build.sh # -> build/BatteryNotify.app (universal)
./package.sh # -> build/BatteryNotify.dmgInstall the result the same way as a downloaded release:
cp -R build/BatteryNotify.app /Applications/
open /Applications/BatteryNotify.appLaunching it straight out of build/ is fine for a quick test, but keep the
copy in /Applications for daily use: both Spotlight and SMAppService skip
apps sitting in arbitrary locations.
Pushing a v* tag builds the app on a macOS runner and publishes the disk image
as a GitHub release:
git tag v1.0
git push origin v1.0workflow_dispatch runs the same build without publishing, leaving the disk
image as a downloadable workflow artifact.
Sources/PowerMonitor.swift event-driven battery state (IOKit)
Sources/AlertPanel.swift the floating warning panel
Sources/AppDelegate.swift menu bar UI and alert logic
Sources/main.swift entry point
Resources/Info.plist bundle metadata (LSUIElement = background app)
Tools/make-icon.swift the app icon, drawn in code
build.sh universal swiftc build + ad-hoc signature
package.sh disk image packaging
.github/workflows/release.yml build and publish on tag