← Back to blog
Behind the build

Why we built a menu bar app for an AI coding tool

April 2026

AI coding tools are getting better at working independently. You can give Claude Code a task, and it'll edit files, run tests, search codebases, and deploy changes across minutes of autonomous work. That's powerful.

But autonomous work creates a new problem: when does it need you?

The attention gap

Claude Code sessions hit permission prompts. They finish responses and wait for your next instruction. They error out on rate limits or API failures. In all three cases, Claude is blocked, and the only way to know is to check.

If you're running one session, checking isn't terrible. But most power users run two, three, five sessions across different projects. The checking overhead compounds fast.

We started counting context switches. On a typical day with three active sessions, we were switching to terminal windows 15-20 times just to check status. Most of those checks found Claude still working, not needing anything.

Why the menu bar

The menu bar is the right abstraction because it's ambient. You don't have to context-switch to get the information. A single icon with a number tells you how many sessions are active. An amber dot means something needs you. No dot means everything is fine.

This is the same pattern macOS uses for Wi-Fi, battery, Bluetooth. Glanceable status that doesn't demand your attention until something changes.

Why native

We built Standby as a native Swift app, not an Electron wrapper. Three reasons:

First, performance. The hook binary that communicates with Claude Code needs to be fast. Under 50ms. A native binary exits before you'd notice it ran.

Second, system integration. Media key control, window focusing by title, notification center integration: these require macOS APIs that work best from native code.

Third, footprint. Standby is 5MB. It uses no RAM when idle. It doesn't bundle a browser engine to show you a dropdown menu.

The hook system

Claude Code has a hook system in ~/.claude/settings.json that fires events on tool use, permission requests, session lifecycle, and more. Standby registers a lightweight binary as a handler for these events. The binary reads event JSON from stdin and forwards it to the app via a Unix domain socket.

This means Standby is read-only. It never modifies Claude's behavior. Exit code 0, no stdout. Your sessions run exactly the same with or without Standby installed.

What we learned

The biggest surprise was how much time we were wasting on status checks we didn't realize we were making. Once Standby was running, the terminal-switching habit faded within a day. You trust the system: if the menu bar doesn't have an amber dot, Claude doesn't need you.

That trust is worth more than any individual feature.