How to Fix React Native Metro Port 8081 Already in Use on macOS Without Restarting Everything
A direct React Native troubleshooting guide for the classic Metro port conflict on macOS, including how to find the process, kill it cleanly, change ports when needed, and recover the dev workflow.
Why this bug is so irritating: it is rarely a real React Native logic bug. It is usually a stale local process problem that interrupts the whole mobile workflow and makes the toolchain feel broken.
What the error usually means
If Metro says port 8081 is already in use, one of these is usually true:
- an old Metro process is still running
- another service grabbed the port
- a previous dev session crashed and left stale state behind
This is a local machine problem first, not a React Native app problem.
Step 1: find what is using port 8081
Run:
lsof -i :8081This shows the process currently bound to that port.
If you want only the PID:
lsof -ti :8081That is the fastest way to stop guessing.
Step 2: kill the stale process cleanly
Once you have the PID:
kill -15 <PID>If it refuses to die and you are sure it is safe to terminate:
kill -9 <PID>Do not start with -9 unless you have to. Normal termination is cleaner.
One-line version
If you are confident the port should be freed:
kill -9 $(lsof -ti :8081)This is useful, but use it intentionally.
Step 3: restart Metro
In your React Native project:
npx react-native startIf the project uses Yarn:
yarn react-native startWhen you might want a different port
Sometimes another tool in your environment is expected to use 8081, or you are working on multiple projects. In that case, changing Metro’s port is cleaner than repeatedly killing processes.
Example:
npx react-native start --port 8088Then make sure the app knows where Metro is expected.
Why stale state also matters
Sometimes the port conflict is only part of the problem. If Metro crashed badly, you may also need to clear temporary state:
watchman watch-del-all
rm -rf $TMPDIR/metro-*
rm -rf node_modules/.cacheThen reinstall or restart if needed:
npm install
npx react-native start --reset-cacheCommon bad reactions
Restarting the whole Mac immediately
That works sometimes, but it teaches nothing and wastes time.
Killing random Node processes
This can break other dev tasks. Check the port owner first.
Assuming the app code caused the failure
Usually the port conflict lives one layer below the app.
When Android debugging is involved
If the app is attached to an Android device or emulator, remember that port forwarding may need attention too:
adb reverse tcp:8081 tcp:8081That command does not solve every Metro problem, but it matters often enough that it belongs in the standard troubleshooting checklist.
It is also worth checking whether another terminal tab quietly started a second Metro process. Duplicate local sessions are a boring cause, but they explain a lot of “I fixed it and it came back” cases.
Final recommendation
Use a calm sequence:
lsof -i :8081
kill -15 <PID>
npx react-native startIf that does not resolve it, clear Metro cache and only then consider alternate ports.
A lot of local mobile frustration comes from treating environment problems like app bugs. Metro port conflicts are a good example of why that distinction matters.