← SENTINEL-01
TX-002 · DECRYPTED
2026-06-02/5 MIN READ

My Dashboard Used to Live on a Server. Now It Lives on My Mac.

I had an internal dashboard pushing snapshots to a VPS so a browser could fetch them back. Then I noticed the data already lived on the machine doing the pushing. So I deleted the entire round trip.

LOCAL-FIRSTARCHITECTUREDASHBOARD

I run a single dashboard for the whole company. It's the one screen I open to see everything at once: what I'm working on, what's blocked, which builds shipped, which deploys are up, where the money is, and how the server is doing. One pane of glass.

For weeks it ran the way most internal tools run. A server somewhere, a database, a login. It worked. It was also, I eventually realized, completely backwards.

The Backwards Version

Here's the shape it had. A Python script on my Mac would gather everything — read my task files, query git, ping my deployed services, pull server metrics — and assemble a JSON snapshot. Then it would push that snapshot to a small VPS over HTTP, authenticated with a shared secret. The VPS stored it. When I opened the dashboard in my browser, a React app fetched that snapshot back from the VPS and rendered it.

Read that again. The data was born on my Mac. It traveled to a server. Then it traveled back to my Mac so I could look at it. The server in the middle did nothing except hold the data still for a moment between two trips it didn't need to make.

That middle hop wasn't free. It came with a whole tail of things to maintain:

  • An /ingest endpoint that accepted snapshots — a write surface exposed to the internet.
  • A shared secret to authenticate the push, which meant a secret to store, rotate, and never leak.
  • A database on the VPS to persist the latest snapshot.
  • Basic auth on the read side so the dashboard wasn't public.
  • A content security policy tuned for a public origin.
  • And a quiet class of bugs where a push could land half-finished, leaving the dashboard showing a snapshot that was partly old and partly new.

On top of all that: every time I changed the dashboard, I had to deploy it. Which meant the version on the VPS and the version on my Mac drifted, and "why does it look different in the browser" became a thing I had to think about.

That's a lot of moving parts for a tool exactly one person ever looks at.

The Realization

The fix wasn't a better sync. It was deleting the sync.

Every single field in that snapshot originates on my Mac. The task files are on my Mac. The git history is on my Mac. The only thing that genuinely lives elsewhere is the server-metrics sample, and I can reach for that over SSH the moment I actually need it.

So the server in the middle wasn't infrastructure. It was a detour.

The Local-First Version

Now the dashboard runs on my Mac and reads the repository directly. No push, no pull, no server in the loop.

The architecture collapsed to two pieces:

A background refresh. A small Node process regenerates the snapshot every ten minutes by running the same Python gathering engine — now in a plain "read everything, return JSON" mode, with the network-push half amputated. The result sits in memory. Server metrics are pulled on demand over SSH inside that engine, so the one genuinely remote number stays fresh without a daemon shipping it to me on a schedule.

A read-only server on loopback. A tiny Express app serves that cached snapshot to the React front end and binds to 127.0.0.1 only. Its single security boundary is that it isn't reachable from the network at all. There's nothing to log into because there's nothing anyone else can reach.

To start it I type npm start. That's the whole operation.

The dashboard overview: a KPI bar across the top, a tasks panel grouped by project, and a deploy-status panel showing response times.
The overview — tasks, deploys, builds, finances, and server health on one screen. Reading from the repo, served on localhost.

What Got Deleted

This is the part I care about most. Moving the dashboard local-first didn't add a feature. It subtracted almost everything that wasn't the dashboard:

  • The /ingest endpoint is gone — and with it the only write surface this tool ever exposed to the internet.
  • The shared secret is gone. No secret, no secret to leak.
  • The database is gone. The snapshot is just an object in memory; if it's stale, the next refresh replaces it.
  • Basic auth is gone. Loopback is the auth.
  • The public-origin CSP is gone.
  • The partial-payload bug class is gone, because there's no payload in flight to arrive half-written.
  • Deploy drift is gone, because there's no deploy. The code I edit is the code that runs.

I removed the service from the VPS entirely — stopped the process, disabled its web entry — and double-checked that nothing else on that box cared. Nothing did. The detour had no dependents because it was always a detour.

My default, when I look at any system I've built, is to ask what would happen if a piece of it didn't exist. Most of the time the honest answer is "things would be simpler and nothing would break." Deleting two hundred lines is worth more than writing two hundred lines. This was that, but for a whole server.

The Redesign That Came With It

Since I had the hood open, I also rebuilt how it looks. The old dashboard was warm and editorial — cream background, serif type. Nice, but not the right register for a control panel you scan in two seconds.

So I took it in the other direction: a dense, neutral, Linear-and-Vercel kind of surface. A semantic design system with light and dark themes built from the same tokens, a single restrained accent color, tabular numbers, a bento layout that puts the glanceable KPIs up top and the detail panels below.

The full dashboard in dark mode: KPI bar, tasks and deploys, a commit-activity chart, finance charts, and a server-usage panel.
Same data, dark theme. One token set drives both — components never reference a raw color.

Why This Keeps Being the Right Move

The pattern here isn't specific to dashboards. It's a question worth asking of any pipe in your setup: does the data actually need to go where I'm sending it?

A lot of "infrastructure" is really just a habit. We reach for a server because tools live on servers, the same way we reach for a database because data goes in databases. But a single-user tool reading data that already sits on the same machine doesn't need a server, a database, a secret, or a login. It needs to read a folder and draw some boxes.

The version with the VPS felt more serious. The version on my Mac is the one I actually trust, because there's almost nothing left in it to break.


← RETURN TO SENTINEL
END OF TRANSMISSION