npm run dev 포트 충돌 해결
How to find and kill processes occupying ports, configure dynamic port assignment, and prevent port conflicts in Node.js development.
npm run dev 포트 충돌 해결
Introduction
The "EADDRINUSE: address already in use" error is a familiar friend to every Node.js developer. Whether it is a crashed process holding the port or multiple projects running simultaneously, port conflicts are inevitable. Here is my definitive guide to handling them.
Environment
node --version
# v20.11.0
# Default port for many frameworks
echo $PORT
# (not set)Problem
Running npm run dev produces this error:
npm run dev
> my-app@1.0.0 dev
> nodemon server.js
[nodemon] 3.0.2
[nodemon] to restart due to changes; press rs
[nodemon] starting `node server.js`
node:events:496
throw er; // Unhandled 'error' event
^
Error: listen EADDRINUSE: address already in use :::3000
at Server.setupListenContext [as _listen2] (node:net:1764:16)
at listenInCluster (node:net:1809:12)
at Server.listen (node:net:1857:5)
at Function.listen (C:\projects\my-app\node_modules\express\lib\application.js:618:24)Analysis
The error means another process is already listening on port 3000. This could be:
- A previous instance of the same server that did not shut down properly
- Another project running on the same port
- A system service using the port
- A zombie process from a crashed development server
Solution
Solution 1: Find and kill the occupying process
# Windows
netstat -ano | findstr :3000
# Output:
# TCP 0.0.0.0:3000 0.0.0.0:0 LISTENING 12345
# Kill by PID
taskkill /PID 12345 /F# macOS/Linux
lsof -i :3000
# Output:
# COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
# node 12345 user 23u IPv6 123456 0t0 TCP *:3000 (LISTEN)
# Kill by PID
kill -9 12345Solution 2: Use environment variable for port
// server.js
const express = require('express');
const app = express();
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
console.log(`Server running on port ${PORT}`);
});# Run on a different port
PORT=3001 npm run devSolution 3: Dynamic port assignment
const net = require('net');
function findAvailablePort(startPort) {
return new Promise((resolve, reject) => {
const server = net.createServer();
server.listen(startPort, () => {
const port = server.address().port;
server.close(() => resolve(port));
});
server.on('error', () => {
resolve(findAvailablePort(startPort + 1));
});
});
}
async function startServer() {
const PORT = await findAvailablePort(3000);
console.log(`Starting server on port ${PORT}`);
app.listen(PORT, () => {
console.log(`Server running on http://localhost:${PORT}`);
});
}
startServer();Solution 4: Kill all node processes
# Windows
taskkill /F /IM node.exe
# macOS/Linux
pkill -f node
# Nuclear option - kill everything on the port
fuser -k 3000/tcpSolution 5: Configure nodemon for automatic port switching
// nodemon.json
{
"watch": ["src"],
"ext": "js,json",
"env": {
"PORT": "3000"
},
"events": {
"crash": "echo 'Server crashed! Check for port conflicts.' && sleep 5 && npm run dev"
}
}// server.js with retry logic
const net = require('net');
function isPortAvailable(port) {
return new Promise((resolve) => {
const server = net.createServer();
server.listen(port);
server.on('listening', () => {
server.close(() => resolve(true));
});
server.on('error', () => resolve(false));
});
}
async function startWithRetry(maxRetries = 5) {
for (let i = 0; i < maxRetries; i++) {
const port = 3000 + i;
if (await isPortAvailable(port)) {
app.listen(port, () => {
console.log(`Server running on port ${port}`);
});
return;
}
console.warn(`Port ${port} is in use, trying next...`);
}
throw new Error('No available ports found');
}Lessons Learned
- Always check port availability before starting - Prevent startup failures
- Use environment variables for ports - Never hardcode port numbers
- Implement graceful shutdown - Ensure your server releases ports on exit
- Use process managers like PM2 in production for automatic restart
- Document required ports in your project README
This blog does not accept any external sponsorships, affiliate marketing, or ad revenue.