Tutorial 5 min read

How to Kill Port 3000 on Mac — The Fast Way

You've seen the error a hundred times: "Port 3000 is already in use." Here's every way to fix it — from the classic Terminal commands to a one-step solution that takes two seconds.

Terminal showing port 3000 already in use error and the lsof command to find the process
Key Takeaways
  • Use lsof -i :3000 to find the process, then kill -9 PID to stop it — the standard Terminal method
  • One-liner alternative: kill -9 $(lsof -t -i :3000) combines both steps into a single command
  • Brow's launcher lets you type "kill port 3000" in natural language and handles everything instantly
  • All methods work for any port — 3000, 8080, 5000, 4200, 5173, and beyond
  • The error happens when a previous dev server didn't shut down cleanly and the process is still running in the background

The Error Every Developer Knows

You sit down, open your project, run npm start or yarn dev or rails server, and instead of your app loading in the browser, you get this:

Error: listen EADDRINUSE: address already in use :::3000

Or the Next.js version:

Port 3000 is already in use.
Use `next dev --port 3001` to use a different port.

Or the Rails version:

A server is already running. Check /tmp/pids/server.pid.

The underlying problem is always the same: something is still listening on port 3000. Maybe you force-quit your terminal yesterday without stopping the server. Maybe a crashed Node process is lingering in the background. Maybe you opened a second terminal tab and forgot the server was already running in the first one. Whatever the cause, the fix is the same — find the process holding the port and kill it.

This is one of those problems that every developer hits regularly but few remember the exact command for. You end up Googling "how to kill port 3000 on Mac" for the twentieth time, scanning through Stack Overflow answers, and copy-pasting the same two commands you've used before. It takes about 30 seconds, which doesn't sound like much until you realize you do it multiple times a week.

Method 1: The Classic Two-Step (lsof + kill)

This is the approach you'll find on every Stack Overflow answer and developer blog post. It works, and it's worth understanding what each part does.

Step 1: Find the process using port 3000.

lsof -i :3000

This outputs something like:

COMMAND   PID   USER   FD   TYPE  DEVICE SIZE/OFF NODE NAME
node    12345  yourname  23u  IPv6  0x1234  0t0  TCP *:hbci (LISTEN)

The important piece is the PID — in this example, 12345. That's the process ID of the Node server hogging port 3000.

Step 2: Kill the process.

kill -9 12345

The -9 flag sends a SIGKILL signal, which forcefully terminates the process. Without it, a hung process might ignore the default SIGTERM signal and keep running. After this command, the port is free and you can restart your dev server.

Method 2: The One-Liner

If you're tired of the two-step dance, you can combine both commands:

kill -9 $(lsof -t -i :3000)

The -t flag tells lsof to output only the PID, without the header row and extra columns. The $() syntax passes that PID directly to kill. One line, one command, done.

You can also use this variant with xargs if multiple processes are on the same port:

lsof -t -i :3000 | xargs kill -9

Both work. Both are annoying to type from memory. Both require you to open Terminal if you don't already have it open.

Method 3: Using npx (for Node developers)

If you're in the Node.js ecosystem, there's a popular npm package called kill-port:

npx kill-port 3000

This works well enough, but it has to download the package the first time (or every time if you don't have it cached), it only works if you have Node installed, and it's still a Terminal command you have to remember and type out. It's a wrapper around the same lsof and kill commands underneath.

Why These Methods Are All a Bit Annoying

Every method above works. But they all share the same friction points:

  • You have to remember the command. lsof -i :3000 is not the kind of syntax that sticks in your brain. Is it -i or -p? Is it a colon before the port or after? Do you need sudo? Every time you need it, there's a moment of hesitation.
  • You need Terminal open. If you're working in VS Code or another editor, you either need to open a new terminal tab or switch to the Terminal app. It's a context switch.
  • You have to parse the output. The two-step method requires you to read the lsof output, find the PID column, copy the number, and type it into the next command. It's not hard, but it's manual and error-prone — especially if there are multiple processes listed.
  • You might kill the wrong process. If you're not careful reading the output, you could kill a different process that happens to be on the same port or misread the PID. Not a catastrophe, but not ideal.

For something you do multiple times a week, these small frictions add up. You shouldn't need to Google the same Terminal command repeatedly for such a basic task.

Method 4: Just Type "Kill Port 3000" in Brow

Here's the approach I've switched to. Brow's launcher understands plain English commands for system tasks, and killing a port is one of them.

  1. Open the Brow launcher (Option+Space or your custom shortcut)
  2. Type kill port 3000
  3. Press Enter

That's it. Brow finds the process on port 3000 and kills it. No PID hunting, no remembering flags, no parsing terminal output. It takes about two seconds from the moment you realize the port is blocked.

This works because Brow's launcher isn't just an app launcher — it's a system command interface. It understands developer-oriented commands like killing ports, checking system resources, and managing processes. Under the hood, it runs the same lsof and kill calls, but you never have to think about the syntax. You just describe what you want in plain language.

And because Brow is built natively in Swift, the launcher opens instantly. There's no Electron startup delay, no loading spinner. You press the shortcut, type the command, and the port is free before you've switched back to your editor.

Comparison: Terminal vs Brow

Aspect Terminal (lsof + kill) Brow Launcher
Steps required 2–3 (find PID, copy, kill) 1 (type & enter)
Command to remember lsof -i :3000 + kill -9 PID "kill port 3000"
Need Terminal open Yes No
Time to complete 15–30 seconds ~2 seconds
Risk of wrong PID Possible (manual parsing) None (automatic)
Works for any port Yes (change the number) Yes (change the number)
Requires Googling syntax Usually, yes No

The Terminal method is perfectly fine if you have the command memorized and you're already in Terminal. But if you're deep in a coding session in VS Code, Xcode, or any other editor, opening the Brow launcher with a keyboard shortcut is faster than switching to Terminal, typing a command you may not remember, and parsing the output.

It Works for Any Port

Port 3000 gets all the attention because React, Next.js, and Rails default to it. But the same problem happens with every popular dev server port:

  • Port 8080 — Spring Boot, Apache Tomcat, many Java servers
  • Port 5000 — Flask, older Create React App versions, AirPlay on macOS Monterey+ (which famously started stealing this port)
  • Port 4200 — Angular CLI
  • Port 5173 — Vite
  • Port 8000 — Django, PHP's built-in server
  • Port 3001, 3002, etc. — Next.js when 3000 is taken (and sometimes these get stuck too)

In Terminal, replace the port number in the command: lsof -i :8080. In Brow, type "kill port 8080". The workflow is identical regardless of which port you need to free up.

A particularly common gotcha on macOS Monterey and later: AirPlay Receiver grabs port 5000 by default. If you're a Flask or Python developer and suddenly can't start your server, check System Settings → General → AirDrop & Handoff and turn off AirPlay Receiver. Or just kill port 5000 — though it'll come back after a restart unless you disable the setting.

When to Use Terminal vs Brow

Use the Terminal commands when you need more control — for example, if you want to inspect the process first to make sure you're killing the right thing, or if you're scripting the kill into a shell script or Makefile. The lsof command gives you rich output (command name, PID, user, protocol) that's useful for debugging.

Use Brow when you just want the port freed up immediately and you don't care about the details. Which, honestly, is 95% of the time. You know what's on port 3000 — it's the dev server you ran earlier. You don't need to inspect it. You just need it gone so you can start a fresh one.

Brow's launcher also handles other developer-adjacent tasks that would normally require Terminal: checking CPU and memory usage, managing clipboard history, taking annotated screenshots, and much more. Once you have the launcher shortcut in muscle memory, it becomes faster than Terminal for any quick system task.

Frequently Asked Questions

How do I find what process is using port 3000 on Mac?

Open Terminal and run: lsof -i :3000. This lists every process listening on port 3000, including the PID (process ID) you need to kill it. Alternatively, Brow's launcher lets you type "kill port 3000" and handles the lookup and kill in one step.

Why does my Mac say port 3000 is already in use?

This happens when a previous dev server (React, Next.js, Rails, etc.) didn't shut down cleanly. The process is still running in the background and holding the port open. You need to find and kill that process before you can start a new server on the same port.

Can I kill any port on Mac, not just 3000?

Yes. The lsof -i :PORT and kill commands work for any port number — 3000, 8080, 5000, 4200, 5173, or any other. In Brow, just type "kill port 8080" (or whatever port number you need) in the launcher and it works the same way.

Try Brow free

Replace 10 Mac apps with one. Free during beta.

Download Free Free during beta · No credit card · macOS 14+