https://github.com/nermalcat69/macstats
macos stats daemon(hardware efficient & minimal)
https://github.com/nermalcat69/macstats
daemon macos stats
Last synced: 7 days ago
JSON representation
macos stats daemon(hardware efficient & minimal)
- Host: GitHub
- URL: https://github.com/nermalcat69/macstats
- Owner: nermalcat69
- License: mit
- Created: 2026-06-03T00:41:03.000Z (about 1 month ago)
- Default Branch: main
- Last Pushed: 2026-06-03T17:34:09.000Z (about 1 month ago)
- Last Synced: 2026-06-20T20:27:45.744Z (17 days ago)
- Topics: daemon, macos, stats
- Language: Rust
- Homepage:
- Size: 120 KB
- Stars: 7
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# MacStats
Personal productivity analytics for your Mac — counts keystrokes, clicks, scroll, and battery health entirely locally.
## Screenshot
## Features
- Keystroke, left/right click, and scroll tracking
- Real-time WPM with 60 s sliding window and burst/repeat filtering
- Battery health, charge %, and cycle count via IOKit (sampled every 5 min)
- Activity sessions with idle detection (60 s threshold)
- Achievements unlocked by lifetime usage milestones
- All data stored locally in SQLite (`~/Library/Application Support/MacStats/macstats.db`)
- SvelteKit web dashboard embedded in the binary — no separate server needed
- CLI for quick stats without opening a browser
## Requirements
- macOS 13 Ventura or later
- [Rust](https://rustup.rs) (stable)
- [Node.js](https://nodejs.org) 18+ (to build the dashboard)
## Install
```sh
# 1. Build the dashboard
cd dashboard
npm install
npm run build
cd ..
# 2. Build the binary
cargo build --release
# 3. Install daemon + launchd agent (run once)
~/.local/bin/macstats install # or: ./target/release/macstats install
```
`install` copies the binary into `~/.local/bin/MacStats.app`, writes a launchd plist, and starts the daemon. Make sure `~/.local/bin` is on your `PATH`.
## Permissions
MacStats needs two permissions under **System Settings → Privacy & Security**:
| Permission | Why |
|---|---|
| **Accessibility** | Required by the AX API to register a trusted process |
| **Input Monitoring** | rdev uses `kCGEventTapOptionListenOnly`; on Sonoma+ this requires a separate TCC grant. Without it the tap starts silently but no events arrive. |
macOS remembers permissions by bundle ID (`com.graycup.macstats`), so you only need to grant them once — even after rebuilding.
After granting both, run:
```sh
macstats daemon restart
macstats accessibility # confirms both are active
```
## Usage
```sh
macstats # today's overview (default)
macstats today # same as above
macstats keyboard # lifetime + today keystroke counts
macstats typing # WPM stats
macstats mouse # click and scroll counts
macstats battery # battery health and charge
macstats uptime # reboots, sleeps, wakes
macstats sessions # recent activity sessions
macstats achievements # unlocked milestones
macstats export json # dump all data as JSON
macstats export csv # daily history as CSV
macstats daemon start | stop | restart | status
macstats accessibility # check/request permissions
```
## Dashboard
```
open http://localhost:8421
```
The dashboard is served by the daemon on port 8421. It is embedded directly in the binary so there is nothing extra to run.
## Updating
```sh
cargo build --release
macstats install
```
`install` replaces the binary inside the bundle and restarts the daemon.
## Architecture
The `macstats` binary doubles as CLI and daemon (`macstats serve`). The daemon runs the rdev event tap on the main thread (required for the macOS CFRunLoop) and spawns a tokio runtime on a background thread for the Axum API server, per-minute aggregation, battery sampling, and system event watching. Metrics are flushed to SQLite every minute and rolled up from minute → hourly → daily → monthly on a schedule. The SvelteKit frontend is compiled to static files and embedded at build time via `include_dir!`.