360
votes

I have a simple Node.js program running on my machine and I want to get the local IP address of a PC on which my program is running. How do I get it with Node.js?

30
food for thought check out joeyh.name/code/moreutils and github.com/polotek/procstreams . I never leave home with out them.Heavy Gray

30 Answers

480
votes

This information can be found in os.networkInterfaces(), — an object, that maps network interface names to its properties (so that one interface can, for example, have several addresses):

'use strict';

const { networkInterfaces } = require('os');

const nets = networkInterfaces();
const results = Object.create(null); // Or just '{}', an empty object

for (const name of Object.keys(nets)) {
    for (const net of nets[name]) {
        // Skip over non-IPv4 and internal (i.e. 127.0.0.1) addresses
        if (net.family === 'IPv4' && !net.internal) {
            if (!results[name]) {
                results[name] = [];
            }
            results[name].push(net.address);
        }
    }
}
// 'results'
{
  "en0": [
    "192.168.1.101"
  ],
  "eth0": [
    "10.0.0.101"
  ],
  "<network name>": [
    "<ip>",
    "<ip alias>",
    "<ip alias>",
    ...
  ]
}
// results["en0"][0]
"192.168.1.101"
233
votes

Running programs to parse the results seems a bit iffy. Here's what I use.

require('dns').lookup(require('os').hostname(), function (err, add, fam) {
  console.log('addr: ' + add);
})

This should return your first network interface local IP address.

219
votes

https://github.com/indutny/node-ip

var ip = require("ip");
console.dir ( ip.address() );
66
votes

Any IP address of your machine you can find by using the os module - and that's native to Node.js:

var os = require('os');

var networkInterfaces = os.networkInterfaces();

console.log(networkInterfaces);

All you need to do is call os.networkInterfaces() and you'll get an easy manageable list - easier than running ifconfig by leagues.

39
votes

Install a module called ip like:

npm install ip

Then use this code:

var ip = require("ip");
console.log(ip.address());
38
votes

Here's my utility method for getting the local IP address, assuming you are looking for an IPv4 address and the machine only has one real network interface. It could easily be refactored to return an array of IP addresses for multi-interface machines.

function getIPAddress() {
  var interfaces = require('os').networkInterfaces();
  for (var devName in interfaces) {
    var iface = interfaces[devName];

    for (var i = 0; i < iface.length; i++) {
      var alias = iface[i];
      if (alias.family === 'IPv4' && alias.address !== '127.0.0.1' && !alias.internal)
        return alias.address;
    }
  }
  return '0.0.0.0';
}
34
votes

Here is a snippet of Node.js code that will parse the output of ifconfig and (asynchronously) return the first IP address found:

(It was tested on Mac OS X v10.6 (Snow Leopard) only; I hope it works on Linux too.)

var getNetworkIP = (function () {
    var ignoreRE = /^(127\.0\.0\.1|::1|fe80(:1)?::1(%.*)?)$/i;

    var exec = require('child_process').exec;
    var cached;
    var command;
    var filterRE;

    switch (process.platform) {
        // TODO: implement for OSes without the ifconfig command
        case 'darwin':
             command = 'ifconfig';
             filterRE = /\binet\s+([^\s]+)/g;
             // filterRE = /\binet6\s+([^\s]+)/g; // IPv6
             break;
        default:
             command = 'ifconfig';
             filterRE = /\binet\b[^:]+:\s*([^\s]+)/g;
             // filterRE = /\binet6[^:]+:\s*([^\s]+)/g; // IPv6
             break;
    }

    return function (callback, bypassCache) {
        // Get cached value
        if (cached && !bypassCache) {
            callback(null, cached);
            return;
        }

        // System call
        exec(command, function (error, stdout, sterr) {
            var ips = [];
            // Extract IP addresses
            var matches = stdout.match(filterRE);

            // JavaScript doesn't have any lookbehind regular expressions, so we need a trick
            for (var i = 0; i < matches.length; i++) {
                ips.push(matches[i].replace(filterRE, '$1'));
            }

            // Filter BS
            for (var i = 0, l = ips.length; i < l; i++) {
                if (!ignoreRE.test(ips[i])) {
                    //if (!error) {
                        cached = ips[i];
                    //}
                    callback(error, ips[i]);
                    return;
                }
            }
            // Nothing found
            callback(error, null);
        });
    };
})();

Usage example:

getNetworkIP(function (error, ip) {
    console.log(ip);
    if (error) {
        console.log('error:', error);
    }
}, false);

If the second parameter is true, the function will execute a system call every time; otherwise the cached value is used.


Updated version

Returns an array of all local network addresses.

Tested on Ubuntu 11.04 (Natty Narwhal) and Windows XP 32

var getNetworkIPs = (function () {
    var ignoreRE = /^(127\.0\.0\.1|::1|fe80(:1)?::1(%.*)?)$/i;

    var exec = require('child_process').exec;
    var cached;
    var command;
    var filterRE;

    switch (process.platform) {
        case 'win32':
        //case 'win64': // TODO: test
            command = 'ipconfig';
            filterRE = /\bIPv[46][^:\r\n]+:\s*([^\s]+)/g;
            break;
        case 'darwin':
            command = 'ifconfig';
            filterRE = /\binet\s+([^\s]+)/g;
            // filterRE = /\binet6\s+([^\s]+)/g; // IPv6
            break;
        default:
            command = 'ifconfig';
            filterRE = /\binet\b[^:]+:\s*([^\s]+)/g;
            // filterRE = /\binet6[^:]+:\s*([^\s]+)/g; // IPv6
            break;
    }

    return function (callback, bypassCache) {
        if (cached && !bypassCache) {
            callback(null, cached);
            return;
        }

        // System call
        exec(command, function (error, stdout, sterr) {
            cached = [];
            var ip;
            var matches = stdout.match(filterRE) || [];
            //if (!error) {
            for (var i = 0; i < matches.length; i++) {
                ip = matches[i].replace(filterRE, '$1')
                if (!ignoreRE.test(ip)) {
                    cached.push(ip);
                }
            }
            //}
            callback(error, cached);
        });
    };
})();

Usage Example for updated version

getNetworkIPs(function (error, ip) {
console.log(ip);
if (error) {
    console.log('error:', error);
}
}, false);
23
votes

Calling ifconfig is very platform-dependent, and the networking layer does know what IP addresses a socket is on, so best is to ask it.

Node.js doesn't expose a direct method of doing this, but you can open any socket, and ask what local IP address is in use. For example, opening a socket to www.google.com:

var net = require('net');
function getNetworkIP(callback) {
  var socket = net.createConnection(80, 'www.google.com');
  socket.on('connect', function() {
    callback(undefined, socket.address().address);
    socket.end();
  });
  socket.on('error', function(e) {
    callback(e, 'error');
  });
}

Usage case:

getNetworkIP(function (error, ip) {
    console.log(ip);
    if (error) {
        console.log('error:', error);
    }
});
20
votes

Your local IP address is always 127.0.0.1.

Then there is the network IP address, which you can get from ifconfig (*nix) or ipconfig (win). This is only useful within the local network.

Then there is your external/public IP address, which you can only get if you can somehow ask the router for it, or you can setup an external service which returns the client IP address whenever it gets a request. There are also other such services in existence, like whatismyip.com.

In some cases (for instance if you have a WAN connection) the network IP address and the public IP are the same, and can both be used externally to reach your computer.

If your network and public IP addresses are different, you may need to have your network router forward all incoming connections to your network IP address.


Update 2013:

There's a new way of doing this now. You can check the socket object of your connection for a property called localAddress, e.g. net.socket.localAddress. It returns the address on your end of the socket.

The easiest way is to just open a random port and listen on it, and then get your address and close the socket.


Update 2015:

The previous doesn't work anymore.

18
votes

Use the npm ip module:

var ip = require('ip');

console.log(ip.address());

> '192.168.0.117'
13
votes

The correct one-liner for both Underscore.js and Lodash is:

var ip = require('underscore')
    .chain(require('os').networkInterfaces())
    .values()
    .flatten()
    .find({family: 'IPv4', internal: false})
    .value()
    .address;
11
votes

Here's what might be the cleanest, simplest answer without dependencies & that works across all platforms.

const { lookup } = require('dns').promises;
const { hostname } = require('os');

async function getMyIPAddress(options) {
  return (await lookup(hostname(), options))
    .address;
}
9
votes

All I know is I wanted the IP address beginning with 192.168.. This code will give you that:

function getLocalIp() {
    const os = require('os');

    for(let addresses of Object.values(os.networkInterfaces())) {
        for(let add of addresses) {
            if(add.address.startsWith('192.168.')) {
                return add.address;
            }
        }
    }
}

Of course you can just change the numbers if you're looking for a different one.

6
votes

I wrote a Node.js module that determines your local IP address by looking at which network interface contains your default gateway.

This is more reliable than picking an interface from os.networkInterfaces() or DNS lookups of the hostname. It is able to ignore VMware virtual interfaces, loopback, and VPN interfaces, and it works on Windows, Linux, Mac OS, and FreeBSD. Under the hood, it executes route.exe or netstat and parses the output.

var localIpV4Address = require("local-ipv4-address");

localIpV4Address().then(function(ipAddress){
    console.log("My IP address is " + ipAddress);
    // My IP address is 10.4.4.137 
});
6
votes

Here's a simplified version in vanilla JavaScript to obtain a single IP address:

function getServerIp() {

  var os = require('os');
  var ifaces = os.networkInterfaces();
  var values = Object.keys(ifaces).map(function(name) {
    return ifaces[name];
  });
  values = [].concat.apply([], values).filter(function(val){
    return val.family == 'IPv4' && val.internal == false;
  });

  return values.length ? values[0].address : '0.0.0.0';
}
6
votes

For Linux and macOS uses, if you want to get your IP addresses by a synchronous way, try this:

var ips = require('child_process').execSync("ifconfig | grep inet | grep -v inet6 | awk '{gsub(/addr:/,\"\");print $2}'").toString().trim().split("\n");
console.log(ips);

The result will be something like this:

['192.168.3.2', '192.168.2.1']
6
votes

I was able to do this using just Node.js.

As Node.js:

var os = require( 'os' );
var networkInterfaces = Object.values(os.networkInterfaces())
    .reduce((r,a) => {
        r = r.concat(a)
        return r;
    }, [])
    .filter(({family, address}) => {
        return family.toLowerCase().indexOf('v4') >= 0 &&
            address !== '127.0.0.1'
    })
    .map(({address}) => address);
var ipAddresses = networkInterfaces.join(', ')
console.log(ipAddresses);

As Bash script (needs Node.js installed)

function ifconfig2 ()
{
    node -e """
        var os = require( 'os' );
        var networkInterfaces = Object.values(os.networkInterfaces())
            .reduce((r,a)=>{
                r = r.concat(a)
                return r;
            }, [])
            .filter(({family, address}) => {
                return family.toLowerCase().indexOf('v4') >= 0 &&
                    address !== '127.0.0.1'
            })
            .map(({address}) => address);
        var ipAddresses = networkInterfaces.join(', ')
        console.log(ipAddresses);
    """
}
5
votes

For anyone interested in brevity, here are some "one-liners" that do not require plugins/dependencies that aren't part of a standard Node.js installation:

Public IPv4 and IPv6 address of eth0 as an array:

var ips = require('os').networkInterfaces().eth0.map(function(interface) {
    return interface.address;
});

First public IP address of eth0 (usually IPv4) as a string:

var ip = require('os').networkInterfaces().eth0[0].address;
3
votes

The following solution works for me

const ip = Object.values(require("os").networkInterfaces())
        .flat()
        .filter((item) => !item.internal && item.family === "IPv4")
        .find(Boolean).address;
3
votes

Google directed me to this question while searching for "Node.js get server IP", so let's give an alternative answer for those who are trying to achieve this in their Node.js server program (may be the case of the original poster).

In the most trivial case where the server is bound to only one IP address, there should be no need to determine the IP address since we already know to which address we bound it (for example, the second parameter passed to the listen() function).

In the less trivial case where the server is bound to multiple IP addresses, we may need to determine the IP address of the interface to which a client connected. And as briefly suggested by Tor Valamo, nowadays, we can easily get this information from the connected socket and its localAddress property.

For example, if the program is a web server:

var http = require("http")

http.createServer(function (req, res) {
    console.log(req.socket.localAddress)
    res.end(req.socket.localAddress)
}).listen(8000)

And if it's a generic TCP server:

var net = require("net")

net.createServer(function (socket) {
    console.log(socket.localAddress)
    socket.end(socket.localAddress)
}).listen(8000)

When running a server program, this solution offers very high portability, accuracy and efficiency.

For more details, see:

3
votes

Based on a comment, here's what's working for the current version of Node.js:

var os = require('os');
var _ = require('lodash');

var ip = _.chain(os.networkInterfaces())
  .values()
  .flatten()
  .filter(function(val) {
    return (val.family == 'IPv4' && val.internal == false)
  })
  .pluck('address')
  .first()
  .value();

The comment on one of the answers above was missing the call to values(). It looks like os.networkInterfaces() now returns an object instead of an array.

3
votes

Here is a variation of the previous examples. It takes care to filter out VMware interfaces, etc. If you don't pass an index it returns all addresses. Otherwise, you may want to set it default to 0 and then just pass null to get all, but you'll sort that out. You could also pass in another argument for the regex filter if so inclined to add.

function getAddress(idx) {

    var addresses = [],
        interfaces = os.networkInterfaces(),
        name, ifaces, iface;

    for (name in interfaces) {
        if(interfaces.hasOwnProperty(name)){
            ifaces = interfaces[name];
            if(!/(loopback|vmware|internal)/gi.test(name)){
                for (var i = 0; i < ifaces.length; i++) {
                    iface = ifaces[i];
                    if (iface.family === 'IPv4' &&  !iface.internal && iface.address !== '127.0.0.1') {
                        addresses.push(iface.address);
                    }
                }
            }
        }
    }

    // If an index is passed only return it.
    if(idx >= 0)
        return addresses[idx];
    return addresses;
}
3
votes

If you're into the whole brevity thing, here it is using Lodash:

var os = require('os');
var _ = require('lodash');
var firstLocalIp = _(os.networkInterfaces()).values().flatten().where({ family: 'IPv4', internal: false }).pluck('address').first();

console.log('First local IPv4 address is ' + firstLocalIp);
3
votes

One liner for macOS first localhost address only.

When developing applications on macOS, and you want to test it on the phone, and need your app to pick the localhost IP address automatically.

require('os').networkInterfaces().en0.find(elm => elm.family=='IPv4').address

This is just to mention how you can find out the ip address automatically. To test this you can go to terminal hit

node
os.networkInterfaces().en0.find(elm => elm.family=='IPv4').address

output will be your localhost IP address.

2
votes

Here's my variant that allows getting both IPv4 and IPv6 addresses in a portable manner:

/**
 * Collects information about the local IPv4/IPv6 addresses of
 * every network interface on the local computer.
 * Returns an object with the network interface name as the first-level key and
 * "IPv4" or "IPv6" as the second-level key.
 * For example you can use getLocalIPs().eth0.IPv6 to get the IPv6 address
 * (as string) of eth0
 */
getLocalIPs = function () {
    var addrInfo, ifaceDetails, _len;
    var localIPInfo = {};
    //Get the network interfaces
    var networkInterfaces = require('os').networkInterfaces();
    //Iterate over the network interfaces
    for (var ifaceName in networkInterfaces) {
        ifaceDetails = networkInterfaces[ifaceName];
        //Iterate over all interface details
        for (var _i = 0, _len = ifaceDetails.length; _i < _len; _i++) {
            addrInfo = ifaceDetails[_i];
            if (addrInfo.family === 'IPv4') {
                //Extract the IPv4 address
                if (!localIPInfo[ifaceName]) {
                    localIPInfo[ifaceName] = {};
                }
                localIPInfo[ifaceName].IPv4 = addrInfo.address;
            } else if (addrInfo.family === 'IPv6') {
                //Extract the IPv6 address
                if (!localIPInfo[ifaceName]) {
                    localIPInfo[ifaceName] = {};
                }
                localIPInfo[ifaceName].IPv6 = addrInfo.address;
            }
        }
    }
    return localIPInfo;
};

Here's a CoffeeScript version of the same function:

getLocalIPs = () =>
    ###
    Collects information about the local IPv4/IPv6 addresses of
      every network interface on the local computer.
    Returns an object with the network interface name as the first-level key and
      "IPv4" or "IPv6" as the second-level key.
    For example you can use getLocalIPs().eth0.IPv6 to get the IPv6 address
      (as string) of eth0
    ###
    networkInterfaces = require('os').networkInterfaces();
    localIPInfo = {}
    for ifaceName, ifaceDetails of networkInterfaces
        for addrInfo in ifaceDetails
            if addrInfo.family=='IPv4'
                if !localIPInfo[ifaceName]
                    localIPInfo[ifaceName] = {}
                localIPInfo[ifaceName].IPv4 = addrInfo.address
            else if addrInfo.family=='IPv6'
                if !localIPInfo[ifaceName]
                    localIPInfo[ifaceName] = {}
                localIPInfo[ifaceName].IPv6 = addrInfo.address
    return localIPInfo

Example output for console.log(getLocalIPs())

{ lo: { IPv4: '127.0.0.1', IPv6: '::1' },
  wlan0: { IPv4: '192.168.178.21', IPv6: 'fe80::aa1a:2eee:feba:1c39' },
  tap0: { IPv4: '10.1.1.7', IPv6: 'fe80::ddf1:a9a1:1242:bc9b' } }
2
votes

Similar to other answers but more succinct:

'use strict';

const interfaces = require('os').networkInterfaces();

const addresses = Object.keys(interfaces)
  .reduce((results, name) => results.concat(interfaces[name]), [])
  .filter((iface) => iface.family === 'IPv4' && !iface.internal)
  .map((iface) => iface.address);
2
votes

Here's a neat little one-liner for you which does this functionally:

const ni = require('os').networkInterfaces();
Object
  .keys(ni)
  .map(interf =>
    ni[interf].map(o => !o.internal && o.family === 'IPv4' && o.address))
  .reduce((a, b) => a.concat(b))
  .filter(o => o)
  [0];
2
votes

Many times I find there are multiple internal and external facing interfaces available (example: 10.0.75.1, 172.100.0.1, 192.168.2.3) , and it's the external one that I'm really after (172.100.0.1).

In case anyone else has a similar concern, here's one more take on this that hopefully may be of some help...

const address = Object.keys(os.networkInterfaces())
    // flatten interfaces to an array
    .reduce((a, key) => [
        ...a,
        ...os.networkInterfaces()[key]
    ], [])
    // non-internal ipv4 addresses only
    .filter(iface => iface.family === 'IPv4' && !iface.internal)
    // project ipv4 address as a 32-bit number (n)
    .map(iface => ({...iface, n: (d => ((((((+d[0])*256)+(+d[1]))*256)+(+d[2]))*256)+(+d[3]))(iface.address.split('.'))}))
    // set a hi-bit on (n) for reserved addresses so they will sort to the bottom
    .map(iface => iface.address.startsWith('10.') || iface.address.startsWith('192.') ? {...iface, n: Math.pow(2,32) + iface.n} : iface)
    // sort ascending on (n)
    .sort((a, b) => a.n - b.n)
    [0]||{}.address;
2
votes

Use:

var os = require('os');
var networkInterfaces = os.networkInterfaces();
var arr = networkInterfaces['Local Area Connection 3']
var ip = arr[1].address;
2
votes

This is a modification of the accepted answer, which does not account for vEthernet IP addresses such as Docker, etc.

/**
 * Get local IP address, while ignoring vEthernet IP addresses (like from Docker, etc.)
 */
let localIP;
var os = require('os');
var ifaces = os.networkInterfaces();
Object.keys(ifaces).forEach(function (ifname) {
   var alias = 0;

   ifaces[ifname].forEach(function (iface) {
      if ('IPv4' !== iface.family || iface.internal !== false) {
         // Skip over internal (i.e. 127.0.0.1) and non-IPv4 addresses
         return;
      }

      if(ifname === 'Ethernet') {
         if (alias >= 1) {
            // This single interface has multiple IPv4 addresses
            // console.log(ifname + ':' + alias, iface.address);
         } else {
            // This interface has only one IPv4 address
            // console.log(ifname, iface.address);
         }
         ++alias;
         localIP = iface.address;
      }
   });
});
console.log(localIP);

This will return an IP address like 192.168.2.169 instead of 10.55.1.1.