Making PortPilot feel instant
Fast here means: you hit the shortcut, the list is already true, kill feels immediate, search does not hitch.
One watcher
The port table is a snapshot on a timer, not a scan on every mouse move. The UI keeps the last snapshot and paints when something actually changed.
:port-watch.ts
function startPortWatch(push: (rows: PortRow[]) => void) {
const tick = async () => push(await window.portpilot.listPorts())
void tick()
const timer = setInterval(() => void tick(), 1500)
return () => clearInterval(timer)
}
~1.5s is a default. Faster feels busy. Slower feels stale. One watcher, not a watcher per row.
Cmd + K runs Fuse over that in-memory list. No disk crawl. Clipboard keeps snippets, not whole files you copied by accident.
:os-to-table
flowchart LR
OS[Operating system]
Main[Main process]
Store[Zustand store]
UI[React table]
OS --> Main --> Store --> UI
Secrets and first screen
Database passwords go to the OS keychain when you save them. Uncheck save and they live in RAM for the session — not in a JSON file next to package.json.
Cold start always opens Ports. Inside a module, the last sub-screen is restored, so JSON → Postgres is not a reset.
What we did not build
No account. No “sync ports to our servers.” No round trip before the list shows. The fastest request is the one you never make.
Last: how this differs from Activity Monitor plus five other apps, and how you install it.