Appearance
Auto Port Selection
Automatically find an available port when the default is occupied. Prevents the common "port already in use" error during development without manual intervention.
When to Use
- Development servers where multiple instances may run simultaneously
- CLI tools that start servers on default ports
- Any server startup where a fixed port is preferred but not required
- Avoiding
EADDRINUSEerrors without manual port management
The Pattern
Use the portfinder package to scan for an available port starting from a preferred default:
javascript
import portfinder from "portfinder";
async function findPort(start = 8000) {
return portfinder.getPortPromise({
port: start,
});
}With a stop limit
Constrain the search range to avoid scanning too far:
javascript
export async function getPort(start) {
const { default: portfinder } =
await import("portfinder");
return portfinder.getPortPromise({
port: start,
stopPort: start + 100,
});
}Respect environment variable
Always prefer an explicit PORT environment variable. Auto-selection is a development convenience, not a production strategy:
javascript
const port = process.env.PORT
? Number(process.env.PORT)
: await findPort(8000);Integration with server startup
Pass the resolved port to app.listen() to start serving:
javascript
const PORT = process.env.PORT || await findPort(8000);
app.listen(PORT, () => {
console.log(`Running at http://localhost:${PORT}`);
});Minimal Express server
A complete example combining port finding with an Express app:
javascript
import express from "express";
import portfinder from "portfinder";
const app = express();
app.get("/", (req, res) => res.send("ok"));
const PORT =
process.env.PORT || await findPort(8000);
app.listen(PORT, () => {
console.log(
`Running at http://localhost:${PORT}`,
);
});
async function findPort(start = 8000) {
return portfinder.getPortPromise({
port: start,
});
}With promisified listen
The promisified listen() helper from the server-startup pattern returns a structured result with the URL already constructed:
javascript
const port = await getPort(3000);
const { url } = await listen(app, port);
console.log(`Server running at ${url}`);Trade-offs
| Approach | Pros | Cons |
|---|---|---|
portfinder | Simple, reliable | Extra dependency |
net.createServer + retry | No dependency | More code, slower |
| Fixed port only | Predictable | Fails on conflict |
Random port (0) | No conflicts ever | Unpredictable URL |
Use auto-selection in development, fixed ports in production. Production deployments should fail loudly if the expected port isn't available — silently switching ports would break load balancers and DNS.