Find and kill ports still running dev servers on your Mac with Portman
A menu bar app that names every dev server on your Mac, and kills the ones you forgot.
- conflict
What Portman shows you that lsof doesn't
Named, not node (pid 10791)
Not node (pid 10791). The project, the framework and its version, read from package.json, lockfiles and Vite's dep cache.
Port in use but nothing answers
A server holding its port but no longer answering looks healthy everywhere else. Portman probes each one and says so.
Conflicts grouped by port
When two things fight over 3000 they get their own heading, with both contenders listed so you can see which to keep.
Preview what each port serves
Expand a row for a live thumbnail of localhost, so you can tell which of your six Astro servers is the one you wanted.
Kill orphaned dev servers
Servers whose project folder is gone, and the ones agent worktrees left behind, fold away with a single Kill all.
Share a port publicly
One click opens a Cloudflare tunnel and copies a public URL, with the Host header rewritten so your dev server accepts it.
Killing a port from the terminal
Two commands, no app required. Find what's holding the port, then stop it by process id. Change the port below and the commands update.
lsof -i :3000The PIDcolumn is the process id you want.
kill 10791Swap in the id from step 1. Add -9 only if it ignores you, since that skips cleanup.
lsof -ti:3000 | xargs killFine when you already know the port is yours. It kills everything listening there without telling you what any of it was, which is the part Portman exists to fix.
What Portman can read, and what it sends
A port manager needs real access to your machine, and you should be suspicious of anything that asks for it. So all of this is checkable.
- Nothing leaves your Mac
- No analytics, no telemetry, no accounts. The only network requests are to your own localhost ports, and to Cloudflare if you explicitly share one.
- Signed and notarised by Apple
- So macOS can verify it hasn't been tampered with since I built it.
- Open source, MIT licensed
- Every line is on GitHub, including the build scripts. Build it yourself if you'd rather.
- Verify what you downloaded
- Run this against the file you downloaded. The expected value is in the release notes for that version.
shasum -a 256 portman-0.2.0.dmgCommon questions about killing ports
lsof -i :3000 and you'll see what's holding it.lsof -i :8080 to find the process id, then kill <pid>. Port 8080 is usually a Java or Spring app, a proxy, or a container publishing a port, so check what it is before you stop it.lsof only shows you your own by default. Try sudo lsof -i :3000. The other case is a process that has died but left the socket in TIME_WAIT, which clears on its own after a minute or so.kill sends SIGTERM, which asks the process to shut down and lets it clean up first. kill -9 sends SIGKILL, which the process can't catch or ignore, so it dies immediately without flushing anything or removing its own files. Start with kill and only escalate if it doesn't respond.sudo for anything owned by root or another user, and kill returns an EPERM error rather than silently failing. Portman shows that error instead of pretending the kill worked.docker stop <name>. Portman resolves forwarded ports back to the container and compose service, and offers Stop container rather than a kill that would take Docker Desktop down with it.lsof and also fuser -k 3000/tcp, which finds and kills in one step. Windows uses netstat -ano | findstr :3000 then taskkill /PID <pid> /F. Portman itself is macOS only.lsof -ti:3000,3001,5173 | xargs kill handles a list. In Portman, search or use a /regex/ and the footer offers to kill everything matching, which is the same idea without having to know the port numbers first.