← Back to projects

macOS · native

hmon

A menu bar monitor for Apple Silicon. Temperature, CPU, memory, disk, network and battery — 35 sensors, sampled every two seconds, in a popover that stays out of the way until you ask for it.

Swift 5.9 SwiftUI AppKit IOKit ServiceManagement macOS 13+

Reading sensors Apple does not publish

Thermal data on Apple Silicon is not part of any public API.

Apple Silicon thermal sensors are exposed through the private IOHIDEventSystemClient interface. There is no header for it and no supported entry point, so hmon resolves the symbols at runtime and matches on temperature event services directly.

Everything else comes from documented ground: IOKit for battery and disk, host statistics for CPU and memory, and interface counters differenced across samples for network throughput.

How a reading reaches the menu bar

Sensor sources feeding a sampler, a model and the SwiftUI popover IOHIDEventSystemClient private · temperature IOKit battery · disk host statistics CPU · memory interface counters network, differenced DispatchSourceTimer every 2.0s · own queue StatsModel rolling 5m series status item the always-on strip PopoverView SwiftUI + sparklines

Sampling runs on its own queue so a slow sensor read never stutters the UI.

What each section shows

Temperature

CPU, GPU and battery in °C, each with its own bar, over a shared 5-minute sparkline.

CPU

Total load with a per-core breakdown behind a disclosure, plus a 5-minute trace.

Memory

Used against total, as a percentage and as a series.

Disk

Used and free, with the percentage the Finder does not put in front of you.

Network

Down and up in KB/s, differenced from interface counters between samples.

Battery

Health as macOS reports it, with the raw numbers behind that figure: cycles, design capacity, voltage, current draw.

Battery health, shown honestly. The headline percentage is what macOS reports, and it is labelled as such. Underneath, hmon shows the raw ratio it was derived from — full charge against design capacity — because those two numbers frequently disagree, and only one of them is measured.

The interface

Screenshots go here. The popover is a tall portrait, so it gets a portrait frame rather than being stretched into a wide one.

The popover All six sections, expanded. assets/hmon-popover.webp
Battery details The raw values behind the health figure. assets/hmon-battery.webp
All sensors The full list of 35. assets/hmon-sensors.webp

The menu bar strip

Rendered here rather than screenshotted, since it is only ever a line of text.

menu bar — always visible
🌡 54.6° 46.6°  28%  19.7G  248G  BAT 88%  ↓217.0K ↑25.5K

Sources

Sensors.swiftRuntime symbol resolution for the private HID event system; temperature services matched and read as floats.
SystemStats.swiftCPU, memory, disk and network counters from documented interfaces.
Battery.swiftHealth, cycles, capacity, voltage and current draw, kept separate because the arithmetic behind "health" deserves its own file.
StatsModel.swiftThe 2-second timer, the rolling 5-minute series, and the deltas that turn counters into rates.
PopoverView.swiftSwiftUI popover, sections and the sparkline drawing.
DesktopWidget.swiftThe desktop-level presentation.
LaunchAtLogin.swiftServiceManagement registration behind the toggle.
AppDelegate.swiftStatus item ownership and anchoring the popover to it.
hmon — built by MilanDroid All projects