whyhot is a deterministic macOS terminal diagnostic that answers “why is my Mac hot?” It combines process activity with macOS power, thermal, battery, display, and uptime signals. Its animated flame changes colour with the diagnosis and intensity with CPU load.
whyhot supports Apple Silicon and Intel Macs. Choose whichever installer you already use.
No permanent install and no Rust toolchain required:
npx whyhotnpm install --global whyhot
whyhotThe npm package bundles both native macOS binaries. It has no runtime dependencies, install scripts, telemetry, or binary downloads.
cargo install whyhot --locked
whyhotThis builds from source and requires a Rust toolchain.
cargo install --git https://github.com/dunctk/whyhot --lockedcargo install --path . --lockedLaunch the live terminal UI:
whyhotThe application list is hidden by default so the full diagnosis stays readable. Press p to show or hide it, then use j/k or the arrow keys to inspect grouped processes.
Print a stable snapshot for scripts or support requests:
whyhot --once --top 15The UI is read-only. It suggests a PID to inspect or stop, but never kills a process. CPU figures are sampled locally using macOS process counters; battery state comes from pmset. No data leaves the Mac.
- A process at 50% CPU is marked warm; 90% is hot.
- Overall CPU at 50% is warm; 80% is hot.
- Per-process disk activity above 10 MiB/s is warm; 50 MiB/s is hot.
- Charging and memory use above 90% are noted as contributing factors.
- Thermal pressure or CPU throttling reported by macOS is hot.
- Battery service conditions and capacity below 80% are flagged.
- External displays and long uptime are reported as possible contributors.
- Spotlight, Photos, backups, updates, iCloud, browsers, video encoders, file sync, virtual machines, WindowServer, and
kernel_taskreceive workload-specific explanations. - Applications are sorted by descending CPU, then disk activity and name; PIDs inside each group are sorted numerically, so equal samples have stable output.
- Helper processes are grouped under their owning application where possible.
- CPU, disk, and known-workload evidence is combined into one finding per application.
- A high reading must persist for three samples before it can be classified as hot; earlier readings are labelled “observing.”
GPU load is inferred from known browser, video, VM, and display workloads because macOS does not expose reliable per-process GPU energy metrics through an unprivileged stable command. Airflow, soft surfaces, direct sunlight, and room temperature are included in the fallback checklist because they cannot be measured in software.
cargo test --locked
cargo clippy --all-targets -- -D warnings
cargo fmt --checkUpdate the Rust and npm package versions together, run the development checks plus cargo package --locked, then publish a GitHub release. Maintainers can publish through the manual Publish to crates.io workflow and the OIDC-authenticated Publish to npm workflow.
MIT
