Skip to content

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 EADDRINUSE errors 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 ​

ApproachProsCons
portfinderSimple, reliableExtra dependency
net.createServer + retryNo dependencyMore code, slower
Fixed port onlyPredictableFails on conflict
Random port (0)No conflicts everUnpredictable 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.