Skip to content

Instantly share code, notes, and snippets.

@mikeal
Created February 16, 2012 01:33
Show Gist options
  • Star 62 You must be signed in to star a gist
  • Fork 8 You must be signed in to fork a gist
  • Save mikeal/1840641 to your computer and use it in GitHub Desktop.
Save mikeal/1840641 to your computer and use it in GitHub Desktop.
get a new/clean port with node.js
var portrange = 45032
function getPort (cb) {
var port = portrange
portrange += 1
var server = net.createServer()
server.listen(port, function (err) {
server.once('close', function () {
cb(port)
})
server.close()
})
server.on('error', function (err) {
getPort(cb)
})
}
@wookiehangover
Copy link

in which semi-colons are "decoration" :trollface:

@mmalecki
Copy link

@mikeal
Copy link
Author

mikeal commented Feb 16, 2012

i prefer copy and pasting 17 lines over taking a dependency :)

@flowonyx
Copy link

Is there an advantage to this over just calling

server.listen(0, ...)

which assigns a random port (http://nodejs.org/docs/latest/api/net.html#server.listen)? I'm assuming it assigns an unused random port, but I can't find anything that actually says that.

@mikeal
Copy link
Author

mikeal commented Feb 16, 2012

in my case i need to know about the port before running an external process so that i can pass it as a commandline flag. deployment is fun! :P

@nisaacson
Copy link

If you don't need the port until after the server is running another option is something like

var server  = http.createServer()
server.listen(0)
server.on('listening', function() {
  var port = server.address().port
})

Taken from here
https://groups.google.com/forum/?fromgroups#!topic/nodejs/SglYxW8YDOs

@aalexgabi
Copy link

It seems that using .listen(0) doesn't guarantee that the port is not used: http://stackoverflow.com/questions/9901043/how-does-node-js-choose-random-ports

@piyush-avantsoft
Copy link

still getting same error.

@7h3kk1d
Copy link

7h3kk1d commented Oct 14, 2014

I'm still getting Error: bind EADDRINUSE. Just less often

@radekstepan
Copy link

If you are looking to get the (randomly assigned) port number:

server.on('listening', function() {
  console.log(server.address().port);
});

@kessler
Copy link

kessler commented Apr 10, 2015

try this: https://github.com/kessler/find-port

can also specify ranges etc...

@1j01
Copy link

1j01 commented Sep 9, 2015

The callback for listen doesn't receive an error object, it's added as a handler for the listening event.

@gauti038
Copy link

gauti038 commented Jan 20, 2017

I just saw that in java, spring takes care of assigning random port. How to do the same in nodejs ?

Copy link

ghost commented Feb 9, 2017

Amazing! Works very well for me (somehow better than node-portfinder 🤔), thanks!

@felipenmoura
Copy link

What about a promisified version

function getAvailablePort (startingAt) {

    function getNextAvailablePort (currentPort, cb) {
        const server = net.createServer()
        server.listen(currentPort, _ => {
            server.once('close', _ => {
                cb(currentPort)
            })
            server.close()
        })
        server.on('error', _ => {
            getNextAvailablePort(++currentPort, cb)
        })
    }

    return new Promise(resolve => {
        getNextAvailablePort(startingAt, resolve)
    })
}

Can be used as promise:

getAvailablePort(3030).then(port => { console.log(`${port} is available`)})

Or with async/await:

async function () {
    // ...
    const port = await getAvailablePort(3000)
    // ...
}

@LucasBadico
Copy link

About this net.createServer() right below getNextAvailablePort definition, you get from where?

@nyn0x
Copy link

nyn0x commented Jun 19, 2018

const net = require('net');

@leviwheatcroft
Copy link

leviwheatcroft commented Sep 21, 2018

see you and raise you @felipenmoura:

import { createServer } from 'net'
function getPort(port = 3000) {
  return new Promise((resolve, reject) => {
    const server = createServer()
    server.on('error', (err) => {
      if (err.code !== 'EADDRINUSE') return reject(err)
      server.listen(++port)
    })
    server.on('listening', () => server.close(() => resolve(port)))
    server.listen(port)
  })
}

usage: const port = await getPort()

@ronen
Copy link

ronen commented Mar 21, 2019

see you and raise you @leviwheatcroft :)

import { createServer } from 'net'
function getPort() {
  return new Promise((resolve, reject) => {
    const server = net.createServer()
    server.on('error', reject)
    server.on('listening', () => (port => server.close(() => resolve(port)))(server.address().port))
    server.listen(0)
  })
}

@jonathantneal
Copy link

I like this game, @ronen: ^_^

import { createServer } from 'net'
function getPort (port = 80) {
  const server = createServer()
  return new Promise((resolve, reject) => server
  .on('error', error => error.code === 'EADDRINUSE' ? server.listen(++port) : reject(error))
  .on('listening', () => server.close(() => resolve(port)))
  .listen(port))
}

Usage

const port = await getPort()

@matthewadams
Copy link

matthewadams commented Jan 3, 2020

@ronen & @jonathantneal, reraise:

import { createServer } from 'net'

function getPort (port = 80, maxPort = 65535) {
  if ((maxPort = parseInt(maxPort)) < (port = parseInt(port))) {
    return Promise.reject((() => {
      const e = new Error('EPORTSPEC')
      e.code = e.message
      return e
    })())
  }
  const server = createServer()
  return new Promise((resolve, reject) => server
    .once('error', error => error.code !== 'EADDRINUSE' || ++port > maxPort ? reject(error) : server.listen(port))
    .once('listening', () => server.close(() => resolve(port)))
    .listen(port)
  )
}

NB: edited to remove port range checks since server.listen has that check; only need to check that maxPort > port.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment