Why I rewrote ShipBoard from Electron to native Swift
I kept missing failed deploys. Our work is spread across AWS CodePipeline, GitHub Actions, GitLab CI, Vercel, and Netlify, and the only way to know if the last deploy went green was to keep five browser tabs open and refresh them like a nervous habit. So I built a little Mac menu-bar app to put them all in one place. I called it ShipBoard.
The first version was an Electron app. It worked — and shipping something that worked mattered more than how it was built. But the longer I lived with it, the more it grated.
What bugged me about the Electron build
For a thing whose entire job is to sit quietly in the menu bar, Electron felt heavy in all the wrong ways:
- Footprint. A bundled Chromium for an app that draws a list of dots. It idled at a few hundred MB of memory and a download in the hundreds of MB — absurd for a status light.
- It never felt native. The menu-bar popover, the fonts, the notifications — close, but always slightly off from what a Mac app should feel like.
- The Mac integrations I wanted were awkward. Reading
~/.awsprofiles, storing tokens in the Keychain, realUNUserNotificationbanners — all doable, but always through a layer.
For a tool people leave running all day, "tiny and native" isn't a nice-to-have — it is the product.
So I rewrote it in Swift
I rebuilt ShipBoard from scratch in Swift and SwiftUI as a proper LSUIElement menu-bar app. The difference is exactly what you'd hope:
- A fraction of the size and memory — a small, signed, notarized, universal binary instead of a Chromium instance.
- It feels like a Mac app, because it is one — native popover, native notifications, native everything.
- The integrations got simple. AWS reads your existing
~/.awsprofiles directly (read-only, SSO or access keys). Provider tokens live in the macOS Keychain and are verified before they're saved. There's no backend — ShipBoard talks straight to each provider, and your credentials never leave your machine.
I'll be honest about the process: the port was a lot of mechanical, cross-language grunt work, and I leaned on Claude Code to move fast. I owned the architecture and reviewed every diff — it was a force multiplier, not autopilot — but it's the reason a from-scratch rewrite was a weekend instead of a month. The unglamorous wins were the best part: it helped me keep a real test suite green and root-cause a gnarly macOS notification bug (turns out the system silently suppresses banners while your app is foreground unless you implement the right delegate).
What ShipBoard is now
One board in your menu bar for every pipeline you ship through — AWS CodePipeline, GitHub Actions, GitLab CI, Vercel, and Netlify. Green when everything's shipping, red the moment it isn't, and a native notification the second a build fails. Multiple accounts and regions, a refresh interval you control, and it polls faster while something's broken.
It's free, it's native, and it runs entirely on your Mac. If you've ever kept five dashboards open just to answer "did it deploy?" — this is the app I wanted.
Stop babysitting dashboards.
Point ShipBoard at your pipelines and forget about it — until it lights up red.
Download for macOS — Free