A native macOS menu-bar app that shows everything listening on your localhost ports and lets you evict it, built in one 97-minute session of Swift and C.
The desktop app in action.
PortPeek is a native macOS menu-bar app that shows everything listening on your localhost ports and lets you evict it without opening a terminal. It lives in the menu bar as an LSUIElement with no Dock icon, and a SwiftUI MenuBarExtra popover lists every LISTEN socket on the machine: a colored dot per process, the port in mono, a human label, and the process name with its PID. Hover a row and you can open it in the browser, copy its address, or kill it behind a two-step confirm.
Under the hood it is a three-second scan loop. A repeating timer shells lsof -iTCP -sTCP:LISTEN, parses the listener table, diffs it against the last pass, and for anything that looks like HTTP it fetches the port and pulls the page title so every server gets a real name, with a Server-header fallback and a hand-picked non-HTTP exclusion set so it never hangs on a database socket. I shell out through a small C popen wrapper because Swift's Process API proved unreliable for this. It is an honest one-session utility: 690 lines of Swift and C across 8 commits in a single 97-minute sitting, a native-macOS breadth piece next to the web and agent work.
Every dev machine collects a graveyard of forgotten servers holding ports. Port 3000 is already in use, some Postgres you forgot is still running, a stray Vite from last week, and finding and killing them means memorizing lsof flags and running kill by hand. PortPeek turns that into a glance at the menu bar and one click.
PortScannerserviceThe three-second scan loop: it runs lsof for every LISTEN socket, diffs against the last pass, HTTP-title-probes each new port for a readable label, and kills a PID on demand.
PortListViewappThe SwiftUI menu-bar popover: a searchable, colored-dot port list with per-row hover actions to open, copy, or two-step-kill, plus empty and no-match states.
CommonPortslibraryThe port-intelligence table: ~110 known ports and ~30 process-name patterns mapped to a readable label and a SwiftUI color for each row's dot.
CShelllibraryA small C popen wrapper used instead of Swift's Process API, which proved unreliable for shelling out to lsof and kill from the menu-bar app.