Which project is using port 3000?
lsof hands you a PID and a binary name. With six dev servers running that
reads as node 41233, node 41871,
node 42104 — and none of them tells you which project you are about
to kill. portman does.
A menu-bar (macOS) or system-tray (Linux) app that lists only your dev servers — with the detected project name and framework — and lets you open, copy, reveal or kill each one in a click. OS daemons are filtered out, so you see what you actually started.
- Detects Node, Bun, Deno, Python, Go, Rust, Elixir, Ruby, PHP, Java, .NET, Ollama
- Reads the project name from
package.json,pyproject.toml,go.mod,Cargo.toml,composer.json - Names the framework: Next.js, Nuxt, Vite, Remix, Astro, SvelteKit, Angular, NestJS, FastAPI, Django, Flask, Rails, Laravel, Spring Boot, Phoenix, Axum
- Per entry: uptime, PID, CPU, memory, and a health dot — does the port still accept connections?
- One static Go binary, a few MB of RAM, ~0% CPU idle. Nothing leaves your machine.
Install
Linux and macOS — npm
npm install -g @forgebay/portman portman
On Linux, if the tray icon does not appear:
sudo apt-get install -y libgtk-3-0 libayatana-appindicator3-1
macOS — Homebrew
brew install forgebay/tap/portman portman
Manual
Grab a binary from the
releases page.
On Linux, extract and run ./portman/install.sh; on GNOME, enable the
AppIndicator and KStatusNotifierItem extension so the tray icon shows.
Just need the command?
# macOS and Linux — what is listening on port 3000 lsof -i :3000 # Linux, without lsof ss -ltnp | grep ':3000'
Kill it
# ask it to shut down cleanly first (SIGTERM) kill -15 <PID> # still there? force it (SIGKILL) kill -9 <PID> # one-liner, macOS and Linux kill -9 $(lsof -ti tcp:3000) # Linux alternative fuser -k 3000/tcp
-15 over -9. SIGTERM lets the
process flush writes and close database connections. SIGKILL gives it no chance —
reach for it only when the polite signal is ignored.
Honest alternatives
Several apps solve this, most of them free. If one fits you better, use it — the list is here so you do not have to go find it.
| App | Platform | Notes |
|---|---|---|
| Ports (BigLittleApps) | macOS 14+ | Free, native SwiftUI. Closest match feature-for-feature. |
| PortWatcher | macOS | Free. SIGTERM then SIGKILL fallback. |
| PortKiller | macOS | Free. |
| devglow | macOS | Free. Also runs your commands, ships an MCP server for AI coding tools. |
| Port Collision Radar | macOS | Free. Watches for a port being taken over. |
| portman | macOS + Linux | Free, MIT. The only one here that runs on Linux; single Go binary. |
So: on macOS you have good free choices. On Linux, portman is the option.
FAQ
Why does the port stay busy after I stop the server?
Usually the parent process died but a child kept the socket, or the socket sits in
TIME_WAIT. lsof -i :3000 shows the difference: a live
LISTEN owner has a PID you can kill, whereas TIME_WAIT clears on
its own within a couple of minutes.
Can I kill a port owned by another user?
Not without elevation. Ports owned by other users or by the system report no PID unless you are root, so portman hides them — it manages your own processes.
Does it phone home?
No network calls, no telemetry, no accounts. It reads local process state and that is all.
Windows?
Not supported. For now: netstat -ano | findstr :3000 then
taskkill /PID <pid> /F.