Mac how-to
How to fix “port 3000 is already in use” on a Mac
Updated · Tested commands for macOS Terminal (zsh or bash)
You run npm run dev and get EADDRINUSE: address already in use :::3000. Something on your Mac is still holding the port, often a dev server from an earlier session or one an AI agent started. Here's how to find it and stop it safely in about a minute, with nothing to install.
Quick answer
Run lsof -nP -iTCP:3000 -sTCP:LISTEN, then kill followed by the PID it shows. Use kill -9 only if it refuses to stop.
Or as one line (stops everything listening on 3000):
kill $(lsof -t -iTCP:3000 -sTCP:LISTEN)
Step by step
-
Find what is listening on port 3000
Open Terminal and run:
lsof -nP -iTCP:3000 -sTCP:LISTEN-nPkeeps addresses and ports as numbers (faster), and-sTCP:LISTENshows only the process that is listening, not every connection to it. Note the number in thePIDcolumn.Example output (example data) COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME node 46210 you 21u IPv6 0x1a2b 0t0 TCP *:3000 (LISTEN)No output? Nothing you own is listening. Try again with
sudoin front in case another user or root owns it, and check Docker withdocker ps, since a container can publish port 3000 too. -
Check what it is before you stop it
Replace
46210with your PID to see the full command and how long it has been running:ps -o pid,ppid, -p 46210etime, command If it's a server you still have open in another Terminal tab, just go there and press Control + C. That's the cleanest stop. To see which project folder it was started from, run
lsof -a -p 46210 -d cwd. -
Ask it to stop
A plain
killsends SIGTERM, which lets the server shut down cleanly:kill 46210Give it a couple of seconds, then run the
lsofcommand from step 1 again. Empty output means port 3000 is free. -
Force it only if it won't quit
If the process is still there after a few seconds, force it:
kill -9 46210kill -9(SIGKILL) can't be ignored, but it also skips cleanup. Child processes the server started may keep running, so check for them withpgrep -P 46210before you force the parent, and stop those first. -
Confirm the port is free and restart
lsof -nP -iTCP:3000 -sTCP:LISTENNo output means you're clear. Start your dev server again with
npm run dev(or your usual command).
Can't stop it? Use another port
If the thing on 3000 is something you need, run your server somewhere else. Both Next.js and Vite accept a --port flag, and the extra -- passes it through npm:
npm run dev -- --port 3001
Seeing this error every day? The cause is usually a dev server that outlived the terminal or AI agent session that started it. Our guide to killing orphaned node processes shows how to find all of them at once.
Questions
Why does it say port 3000 is in use when nothing is running?
Something usually is, just not in a window you can see: a server from a closed terminal, an AI agent session or a crashed editor. lsof -nP -iTCP:3000 -sTCP:LISTEN will find it. If that shows nothing, try it with sudo and check docker ps.
Is kill -9 bad?
Not bad, just blunt. It stops the process instantly with no chance to clean up, so files may be left half written and child processes can keep running. Use plain kill first.
I killed it and the port got taken again straight away. Why?
Something is restarting it: a file watcher like nodemon, a process manager like pm2, a Docker container with a restart policy, or a parent process that respawns its worker. Find the parent with ps -o ppid= -p PID and stop that instead.
Does this work for other ports like 5173 or 8080?
Yes. Swap 3000 for any port number in the commands. For 5000 or 7000, check whether it's macOS AirPlay Receiver first (see find what's using a port).