Every developer dashboard I've used is either a browser tab I forget about or an Electron app that eats 200MB of RAM to show me three numbers.
I wanted something different. Something that sits quietly in the menu bar, shows me what I need, and gets out of the way. So I built Pulse.
The Problem
My daily workflow involves juggling multiple AI coding tools — Claude Code, Codex, OpenRouter — each with their own usage dashboard in a separate browser tab. On top of that, I run several local services (Postgres, Redis, a couple of dev servers) that occasionally die without telling anyone.
The checking ritual looked like this every morning:
- Open Claude Code dashboard — check remaining quota
- Open Codex usage page — check remaining quota
- Open OpenRouter balance — check remaining credits
- Run
ps aux | grep postgres— is it alive? - Hit localhost:6379 — is Redis responding?
Five context switches before I've written a single line of code. And if something died overnight, I'd only find out when a build failed or an API call timed out.
Why Not Electron?
The obvious path would have been Electron. Faster to ship, cross-platform out of the box, massive ecosystem. I've built Electron apps before and the DX is genuinely good.
But this app lives in the menu bar. It runs all day, every day. For something with that kind of residency, the numbers matter:
| Electron | SwiftUI (Pulse) | |
|---|---|---|
| Binary size | ~150-200MB | 15MB |
| Idle RAM | ~80-120MB | ~12MB |
| Startup time | 2-4 seconds | < 1 second |
| Native notifications | Via bridge | Native |
| Dark mode | CSS hacks | Automatic |
| Menu bar integration | Limited | First-class |
For a full application with complex UI, Electron makes sense. For a status glance that should feel like part of the OS, native wins.
What Pulse Actually Does
Click the menu bar icon and you see two things:
Service status — green/red indicators for each local service Pulse monitors. If Postgres went down at 3am, you see it immediately when you open your laptop. No more discovering dead services through cascading errors.
AI quota — current usage across Claude Code, Codex, and OpenRouter in one view. When you're burning through tokens faster than usual, you catch it early instead of hitting a rate limit mid-session.
That's it. No charts, no historical data, no analytics dashboard. Just the current state of things you need running.
The Tradeoffs
Honesty time:
- Mac-only. No cross-platform story. If you're on Linux or Windows, this doesn't help you. For a menu bar utility, I think that's the right call — menu bar apps are a Mac pattern.
- SwiftUI is still maturing. Some things that would take 5 minutes in React took an hour of fighting with SwiftUI's layout system. The ecosystem is smaller and Stack Overflow has fewer answers.
- No web technologies. Can't just npm install a charting library. Everything is built with native frameworks, which means more upfront work for each new feature.
- Polling, not pushing. Pulse checks service status on an interval rather than receiving push notifications. Good enough for the use case, but not real-time.
Would I make the same choice again? Yes. The result feels right — fast, small, quiet. The kind of utility that disappears into your workflow.
What I Learned
Building a small native app after years of web development was humbling. Things I took for granted (hot reload, flexbox, npm) weren't there. But the constraints forced better decisions:
- Fewer dependencies meant fewer things to break
- Native APIs meant less glue code
- Small binary meant fast iteration on the actual product
If you're considering building a small Mac utility, SwiftUI is worth the learning curve. The menu bar API is straightforward, the app lifecycle is simple, and the result feels like it belongs on the platform.
Top comments (0)