Lab
Dev hub
Small toolEvery local dev tool behind one port, in a tabbed shell.
Dashboard/dashboard/
Open items12
Due this week3
Done27
Review board/review/
Open reviews4
Waiting on me2
Merged18
Docs/docs/
Pages38
Drafts2
Broken links0
$ hub routes --print
# Caddy: copy into the Caddyfile, then reload
hub.example.invalid {
handle /dashboard/* { reverse_proxy localhost:5101 }
handle /review/* { reverse_proxy localhost:5102 }
handle /docs/* { reverse_proxy localhost:5103 }
handle { reverse_proxy localhost:5100 }
}
# Tailscale: run these yourself
tailscale serve --bg --set-path /dashboard http://localhost:5101
tailscale serve --bg --set-path /review http://localhost:5102
printed, not run
How it works
- One config file lists the tools. Each entry has a name, a local address and a route, by hostname or by path.
- The hub serves a tabbed shell on one port. Each tab frames one tool, so I switch between them without remembering addresses.
- Edits go through an atomic write API. It writes to a temporary file and renames it, and only accepts loopback and same-site requests.
- A poll marks each tool up or down. Every 10 seconds the hub checks each address and the tab dot changes color.
- Proxy commands are printed, not run. The hub generates the Caddy and Tailscale serve commands from the config and leaves running them to me.
Built with
- Node, no dependenciesThe whole hub: static shell, routing, health poll and the config API, with an empty package list.
- CaddyOptional front door for hostname routing, configured from the printed snippet.
- TailscaleReaches the hub from other devices through serve commands the hub prints.
Decisions
- Path routing over hostname routing, in writing. Login cookies and keyboard focus inside frames both need one origin, and separate hostnames break them. Hostnames stay available for tools that cannot live under a path.
- Print the proxy commands, never run them. Changing a proxy or a network setting is a system change, so the hub shows it and I decide when it happens.
- Zero npm dependencies. A tool that only routes and polls has nothing to gain from a package tree, and nothing to update or audit later.