For developers
How to find and stop what is running on port 3000 on a Mac
EADDRINUSE means something already holds the port. Here is how to find it with lsof, stop it safely with kill, avoid the common one-liner trap, and how Orrel shows every localhost port with the project and the tool that started it.
You run npm run dev and get Error: listen EADDRINUSE: address already in use :::3000. Something is already listening on the port: usually a dev server from earlier whose terminal tab you closed, or one an AI coding agent started and left behind.
Find it with lsof
Open Terminal and ask which process is listening on the port:
lsof -nP -iTCP:3000 -sTCP:LISTEN
The output shows the command name, the process ID (PID) and the user. -n and -P skip name lookups so it answers instantly, and -sTCP:LISTEN shows only the process that owns the port. The shorter lsof -i :3000 works too, but also lists every program connected to the port, including your browser.
To see the folder the process is running in, which tells you which project it is:
lsof -p 12345 | grep cwd
Replace 12345 with the PID. To see what started it, look at its parent:
ps -o pid,ppid,command -p 12345
Stop it
kill 12345
Plain kill sends SIGTERM, which asks the process to shut down cleanly. Check the port again after a couple of seconds. If it is still there:
kill -9 12345
SIGKILL ends it immediately, with no chance to tidy up.
The one-liner, and its trap
You will often see kill -9 $(lsof -ti:3000) recommended. -t prints PIDs only, which is handy, but without a state filter it includes every process connected to port 3000, which can be your browser. A safer form:
lsof -ti tcp:3000 -sTCP:LISTEN | xargs kill
Why ports get left behind
- Closed terminal tabs. Closing a tab normally ends what was running in it, but processes started in the background or by tools such as
nohupsurvive. - Child processes.
npm run devstarts a node process, which may start more. Stopping one can leave the others holding ports. - AI coding agents. Agents start dev servers to test their work. When the session ends, the server can keep running with no terminal attached.
- macOS itself. AirPlay Receiver listens on ports 5000 and 7000, which clashes with some frameworks' defaults.
Activity Monitor can quit a process too, but it does not show ports, so you need the name or PID from lsof first.
How Orrel does it
Orrel's Running screen lists every port your processes are listening on, with the project folder, the dev tool (Next.js, Vite, Wrangler and others) and what started it: Claude Code, Codex, Cursor, a terminal, or nothing any more. A row reads like :3000, field-notes, Next.js, ~/code/field-notes, Claude Code, 2 h, which answers the question without three commands.
- Stop the whole thing. Stop climbs from the listening process to the command you actually ran and stops that, with everything it started. A first press asks politely; a second press forces it.
- Left running. Processes whose terminal or agent has quit are listed separately, so you can stop them all at once.
- Open in browser. One click opens the port's address.
- Memory and CPU. Below the ports, apps and agent sessions with their helper processes added together.
- From the menu bar. The same list is a click away without opening the window.
Where Orrel stops
Orrel shows and stops your own processes only. Anything running as root or another user, and macOS services such as AirPlay Receiver, are left alone, so use Terminal with sudo for those. A port published by Docker shows Docker's own process, not the container inside it; use docker ps to see which container has it. Orrel recognises common dev tools by their command lines, and a tool it does not know is still listed, just without a label.
Questions
What is using port 5000 on my Mac?
Often AirPlay Receiver, which macOS runs on ports 5000 and 7000. Turn it off in System Settings › General › AirDrop & Handoff if you need those ports for development, or run your server on another port.
Is kill -9 safe?
It stops a process immediately, without letting it save anything or close connections. Try a plain kill first, which asks the process to shut down, and use -9 only if it does not exit after a few seconds.
Why does my dev server keep coming back after I kill it?
You probably stopped a child process and its parent restarted it, or a file watcher relaunched it. Stop the command you started, such as the npm or pnpm process, rather than the node process under it.