bradtraversy.dev — portdoc.mdx
● home.md ▸ projects/ × ▸ tools/ ▸ devlog/ ▸ articles/ ● now.md ● about.md
// project

# PortDoc

a local control panel for running dev servers, ports, conflicts, and stale processes

live v0.1.2 Rust ·Axum ·React ·TypeScript ·Vite ·Tailwind ·cargo-dist ·Astro
PortDoc dashboard showing running service counts, active local project rows for ai-skills-directory, portdoc, and startdev, plus grouped local ports

what it does

PortDoc opens a local web ui that answers the annoying questions around dev servers:

  • what is running across local ports and dev services
  • which project owns it based on process metadata and project-root hints
  • what url to open for each local app or api
  • why a port is taken when a server starts on the wrong number or fails
  • what looks stale from an old terminal tab or forgotten repo
  • which services are exposed as local-only, lan-visible, docker-bound, or unknown
  • how to install it from portdoc.dev on Linux, macOS, and Windows

the terminal launches it. the browser is the product.

PortDoc can also run in the background using the operating system’s own process manager: systemd --user on Linux, a LaunchAgent on macOS, or Task Scheduler on Windows. The CLI handles status, stopping, and disabling startup. Stopping the process and removing its sign-in startup entry are separate actions.

why i built it

i constantly have a few local apps running at once: astro, next, vite, node apis, workers, local databases, docker containers, and the occasional process that should have died yesterday. the usual answer is some mix of lsof, ss, ps, memory, and guessing.

that is fine once. it is not fine as a daily workflow. i wanted a calm dashboard that thinks in projects, apps, ports, and urls, not raw socket trivia.

how it’s built

a quick tour:

  • rust single binary: the app runs locally and ships as one executable
  • axum server: serves the browser ui and exposes the local snapshot api
  • embedded vite app: react and typescript for the dashboard, bundled into the binary for release builds
  • snapshot contract: one json shape feeds the ui and portdoc --json
  • platform probes: linux, macOS, and Windows adapters collect socket and process metadata with unknown owners treated as data, not failure
  • dashboard ui: project cards, services table, status callouts, actions, and a graphite theme tuned for quick scanning
  • release pipeline: cargo-dist builds the release artifacts, pushes the Homebrew tap, and signs Windows binaries for v0.1.1
  • astro site: portdoc.dev is the public install page and keeps /install.sh plus /install.ps1 as 307 redirects to GitHub Release assets

what’s next

v0.1.2 is public, with background mode and signed Windows binaries. Background upgrades still need an explicit stop, upgrade, and start. Improving that lifecycle is more useful than adding another dashboard counter.

the win is not seeing more network data. the win is knowing which old dev server is blocking the thing i actually want to run.

## more screenshots

PortDoc screenshot 1

## recent devlog

// devlog entries tagged project: portdoc
→ all devlog
// EOF portdoc.mdx
main
●
portdoc.mdx
UTF-8
LF
Markdown
Ln 1, Col 1