427

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?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
yojimbo87
  • 65,684
  • 25
  • 123
  • 131

43 Answers43

564

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
        // 'IPv4' is in Node <= 17, from 18 it's a number 4 or 6
        const familyV4Value = typeof net.family === 'string' ? 'IPv4' : 4
        if (net.family === familyV4Value && !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"
Pawel
  • 16,093
  • 5
  • 70
  • 73
nodyou
  • 5,680
  • 1
  • 14
  • 2
  • 20
    var _ = require('underscore'); var ip = _.chain(require('os').networkInterfaces()).flatten().filter(function(val){ return (val.family == 'IPv4' && val.internal == false) }).pluck('address').first().value(); console.log(ip) – Carter Cole Sep 09 '13 at 15:27
  • The sixth line should be `if( details.family=='IPv4' && details.internal === false ) {` if you just want external IPs. – Arlen Beiler Aug 18 '14 at 22:38
  • 4
    @CarterCole you need an extra call to .values() before flatten. – Guido Mar 04 '15 at 09:41
  • I tried npm install os and it said 'os' wasn't in the npm registry – Alexander Mills May 08 '15 at 22:23
  • This probably more useful to visualize the object: `console.log(JSON.stringify(ifaces, null, 2));` -- @AlexMills "os" is a core nodejs module. No need to npm install it. – Cory Mawhorter May 16 '15 at 21:56
  • oh i see, i didnt know 'os' was a core module – Alexander Mills May 16 '15 at 23:05
  • 5
    What if I wanted to retrieve just the active interface's IP address? – Tejas Aug 02 '15 at 06:54
  • what if i want to get the dns address of each interface.?? – taha027 Jan 25 '16 at 09:57
  • Lodash: `address = _(ifaces).values().map(a => _.find(a, { family: 'IPv4'})).compact().map('address').value()` – ninhjs.dev May 07 '17 at 14:54
  • 25
    one-liner without lodash for **node >= 7.0.0**: `Object.values(require('os').networkInterfaces()).reduce((r, list) => r.concat(list.reduce((rr, i) => rr.concat(i.family==='IPv4' && !i.internal && i.address || []), [])), [])` – som Jan 17 '19 at 00:15
  • 19
    "Underscore" "lowdash" "one liner" - gross. – B T Jun 12 '20 at 15:43
  • Minor point @ArlenBeiler but the OP's logic is correct. If its not ipv4 or its not internal, return from the callback straight away, don't output anything. – Joseph Thomas-Kerr Jun 22 '20 at 00:53
  • 2
    simpler one-liner without reduce (returns undefined when none is found) `[].concat(...Object.values(require('os').networkInterfaces())).find(x => !x.internal && x.family === 'IPv4')?.address` – Gregor Mitscha-Baude Jun 14 '21 at 12:46
  • ` const familyV4Value = typeof net.family === 'string' ? 'IPv4' : 4 ; if (net.family === familyV4Value && !net.internal) { ...` just curious why won't user `if (net.family === 'IPv4' || net.family === 4)` – Danish ALI Jul 04 '22 at 01:52
  • @GregorMitscha-Baude, I wonder how to type check that in typescript – sryscad Feb 01 '23 at 09:06
253

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.

Wharbio
  • 1,355
  • 10
  • 16
Xedecimal
  • 3,153
  • 1
  • 19
  • 22
  • 5
    @HermannIngjaldsson: This is not a very thoroughly informative criticism. Could you be more specific? Maybe take the example code and put it into a new question providing more details and asking why it doesn't work? – Xedecimal Nov 07 '12 at 20:11
  • 14
    It is not always a good idea to use the DNS lookup, as it can return wrong information (i.e. cached data). Using 'os.networkInterfaces' is a better idea in my opinion. – Guido Feb 28 '13 at 19:55
  • 4
    Using DNS works if your server has a dns entry somewhere. However in a lot of applications there isn't a dns entry (e.g. my laptop). os.networkInterfaces() is probably the way to go. – Jeff Whiting Feb 06 '15 at 20:54
  • 2
    Note that this uses the OS lookup, which doesn't necessarily do DNS lookups and should know its own primary IP address... – w00t Sep 03 '15 at 10:09
  • what if i get the DNS address of each interface – taha027 Jan 25 '16 at 09:58
  • I know this is already a few days old and I might need some sleep here, but I can't get the address out of the callback... I tried just console.log'ing (without the console.log in your block), but that just gave me an object with the unresolved hostname, the family and an oncomplete function? `console.log(require('dns').lookup(require('os').hostname(), function (err, addr, fam) { }));` is what I used. Your code works perfectly fine for console output, but I need/want the IP in a variable and I can't get my head around it right now – Tarulia Dec 07 '16 at 00:36
  • This returns inconsistent results. I get `127.0.1.1` running Ubuntu 16.10. Would recommend using `os.networkInterfaces()`. – dragon Dec 28 '16 at 19:29
  • os.networkInterfaces() doesn't return any interfaces on SunOS 5.11 – Michael Jan 29 '17 at 21:24
  • @Offirmo, I've got my local network IP. like 192.168.0.101 – vovchisko Jun 30 '17 at 16:40
  • can you please help me to sovle this https://stackoverflow.com/questions/52241799/failed-to-compile-node-modules-macaddress-lib-windows-js-in-angular-5 @Xedecimal – Zhu Sep 09 '18 at 09:41
  • This method randomly throws IPv6 like ::1 for localhost, so it's not very reliable. – Kactung Jun 18 '23 at 01:24
240

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

var ip = require("ip");
console.dir ( ip.address() );
Jan Jůna
  • 4,965
  • 3
  • 21
  • 27
  • 2
    documentation for this package is unclear... can i also get the broadcast address, or do i have to supply it myself? – Michael Jan 29 '17 at 21:33
  • @Michael you can look at the code, its open-source. – majidarif Feb 04 '17 at 05:30
  • 22
    @majidarif i don't recognize that as a valid excuse for poor documentation – Michael Feb 15 '17 at 15:11
  • The [docs](https://github.com/indutny/node-ip#usage) now show `ip.subnet()` contains `broadcastAddress`. – Stephen Last Mar 06 '17 at 15:56
  • 9
    This works incredibly well. Getting the IP address is literally a one-liner. Excellent. – EvSunWoodard Jul 25 '17 at 20:41
  • as @cburgmer says: _"Sometimes it does make sense to scroll to the end of all the answers"_. And that's true... It is not necessary to write all the code above (first two answers - _although thanks them, for sharing their experiences_)... they were already done, I presume, packaged in this module. – Ualter Jr. Oct 13 '17 at 07:36
  • 7
    It doesn't give you the IP address of all the adapters. If you have Docker installed, it gives the vEthernet docker address instead of your actual Ethernet address – TetraDev Dec 19 '17 at 21:52
  • simply the best! – 0xh8h Dec 29 '17 at 14:04
  • Shows a different address from Ipconfig (IPv4) in Windows. Does anyone know why? – Ben Carp Mar 10 '20 at 16:36
  • This module "ip" internally uses the same module "os" as explained in the accepted answer. – roneo Oct 05 '20 at 17:25
  • 1
    This module is 416 lines and 10Kb just to get an IP address... way overkill – Ryan Wheale Nov 16 '21 at 20:53
75

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.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Edoardo
  • 759
  • 5
  • 3
43

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';
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
jhurliman
  • 1,790
  • 1
  • 18
  • 20
  • Coffee version: `getLocalIP = (interfaceName = "en0",version = "IPv4")-> iface = require('os').networkInterfaces()[interfaceName] for alias in iface if (alias.family == version && !alias.internal) return alias.address return "0.0.0.0"` – Jay Mar 24 '15 at 20:58
42

Install a module called ip like:

npm install ip

Then use this code:

var ip = require("ip");
console.log(ip.address());
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Gokul
  • 1,130
  • 13
  • 18
40

Use the npm ip module:

var ip = require('ip');

console.log(ip.address());

> '192.168.0.117'
Alexis Tyler
  • 1,394
  • 6
  • 30
  • 48
KARTHIKEYAN.A
  • 18,210
  • 6
  • 124
  • 133
34

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);
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
user123444555621
  • 148,182
  • 27
  • 114
  • 126
  • Tested just now on OSX Lion, perfect. Thanks so much! – T3db0t May 03 '12 at 21:49
  • I had to remove the hyphen after the word "IP" in your Windows regexp, because my output didn't have the hyphen (I'm using Windows XP 32-bit). I don't know if that was a typo or if your Windows version really outputs a hyphen after "IP", but just to be on the safe side, I suppose it can be made optional: `filterRE = /\bIP-?[^:\r\n]+:\s*([^\s]+)/g;`. Aside from that, great script, a true lifesaver. Many thanks! – User not found Jul 06 '12 at 18:14
  • @jSepia: That's probably a localization thing. German Windows prints "IP-Adresse" ;) – user123444555621 Jul 06 '12 at 18:19
  • Fair enough, but now you broke it again :p My ipconfig output doesn't include "v4" nor "v6", that seems to be a Vista/7 thing (see http://technet.microsoft.com/en-us/library/bb726952.aspx ) – User not found Jul 06 '12 at 23:40
  • There is no reason for such a hack. We have os.networkInterfaces() now. – Brad May 18 '13 at 02:56
  • It is not ideal to pipe the output of a console command when there is any kind of solution available that is integrated into the language and made for its use. – trevorKirkby Jan 16 '14 at 17:57
  • At coffee shops I was always getting the wrong IP. So now I use this when I want to update my AWS security groups with my current ipv4. sorry in advance for the formatting, but i didn't want to add a new answer on page 2 to 30 existing answers. function getMyIP(cb){ var cmd_str = "dig +short myip.opendns.com @resolver1.opendns.com", { exec } = require("child_process"); exec(cmd_str, (error, stdout, stderr) => { cb(null, stdout.trim()); }); } – fullstacklife Oct 22 '20 at 00:31
24

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);
    }
});
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Jimbly
  • 348
  • 2
  • 5
  • In case you're wondering - this does not necessarily get the public IP address that the world sees. – artur Sep 21 '11 at 16:05
  • Would be a nice solution if it didn't depend on internet connection and its speed.. – Jacob Rask Nov 01 '11 at 10:21
  • In my instance this solution is perfect, as I need to know the IP of the interface a particular request goes out on. – radicand Oct 18 '13 at 05:05
  • This is the only thing that worked to grab my local IP address reliably, without needing the user to specify the interface name, thank you! – Sv443 Feb 14 '22 at 20:18
19

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.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Tor Valamo
  • 33,261
  • 11
  • 73
  • 81
  • Does that mean that to get the network address in nodejs you need to make a system call to `ifconfig` or `ipconfig` and parse the response string? – user123444555621 Sep 18 '10 at 08:38
  • @Pumbaa80 - Pretty much, unless your network card has some drivers you can call. Also if you have several network cards (or adapters, like hamachi), there is no way you can just call a function of sorts and get one IP which is _THE_ IP. So parsing it and interpreting the output of of `ifconfig` is pretty much the only way. – Tor Valamo Sep 18 '10 at 17:25
  • It looks like `net.socket` returns `undefined` as of 2015, so the "new way of doing this" doesn't work anymore. There is a `net.Socket`, but it does not have a `localAddress` property. – trysis Apr 09 '15 at 16:40
13

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;
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
vault
  • 3,930
  • 1
  • 35
  • 46
  • 3
    You can use: `.find({family: 'IPv4', internal: false})` as well for a shorter more elegant code – dcohenb Mar 27 '16 at 11:16
11

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;
}
user87064
  • 127
  • 1
  • 5
11

I probably came late to this question, but in case someone wants to a get a one liner ES6 solution to get array of IP addresses then this should help you:

Object.values(require("os").networkInterfaces())
    .flat()
    .filter(({ family, internal }) => family === "IPv4" && !internal)
    .map(({ address }) => address)

As

Object.values(require("os").networkInterfaces())

will return an array of arrays, so flat() is used to flatten it into a single array

.filter(({ family, internal }) => family === "IPv4" && !internal)

Will filter the array to include only IPv4 Addresses and if it's not internal

Finally

.map(({ address }) => address)

Will return only the IPv4 address of the filtered array

so result would be [ '192.168.xx.xx' ]

you can then get the first index of that array if you want or change filter condition

OS used is Windows

MK.
  • 752
  • 1
  • 8
  • 12
9

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.

mpen
  • 272,448
  • 266
  • 850
  • 1,236
  • What if the address does not start with `192.168` ? – anu Aug 07 '19 at 03:31
  • @anu Either change the prefix to the one you're looking for, or use one of the many other solutions that people have posted here :-) My local IP always start with `192.168.` which is why I chose that. – mpen Aug 07 '19 at 17:52
8

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

function getServerIp() {

  const os = require('os');
  const ifaces = os.networkInterfaces();
  let 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';
}
SimoAmi
  • 1,696
  • 14
  • 13
8

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);
    """
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Sy Le
  • 79
  • 1
  • 2
7

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']
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Soyoes
  • 940
  • 11
  • 16
7

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.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Tarandeep Singh
  • 1,322
  • 16
  • 16
6

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 
});
Ben Hutchison
  • 4,823
  • 4
  • 26
  • 25
5

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;
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
KyleFarris
  • 17,274
  • 5
  • 40
  • 40
  • Keep in mind that these one-liners are platform specific. On OS X, I have `en0` and `en1` for ethernet and wifi. On Windows, I have `Local Area Connection` and `Wireless Network Connection`. – xverges Jul 29 '13 at 10:39
  • If you want to know about your public remote IP (On OS X), use: var ip = require('os').networkInterfaces().en0[1].address; – Marcelo dos Santos Apr 26 '16 at 13:47
3

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:

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Krizalys
  • 121
  • 5
3

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.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
nwinkler
  • 52,665
  • 21
  • 154
  • 168
  • 1
    I <3 lodash. Especially lodash golf! The `_.chain(..)` can be re-written as `_(...)`, the `.filter(..)` can be re-written as `.where({family: 'IPv4', internal: false})`, and you can drop the final `value()` because `.first()` does it for you when chaining. – Ryann Graham Jun 17 '15 at 22:38
3

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;
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
origin1tech
  • 749
  • 6
  • 16
3

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);
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
3

The following solution works for me

const ip = Object.values(require("os").networkInterfaces())
        .flat()
        .filter((item) => !item.internal && item.family === "IPv4")
        .find(Boolean).address;
FDisk
  • 8,493
  • 2
  • 47
  • 52
  • 2
    Very nice. Slight tweak in case none is found: const ip = Object.values(require("os").networkInterfaces()).flat().reduce((ip, {family, address, internal}) => ip || !internal && family === 'IPv4' && address, ''); – x0a Nov 08 '20 at 19:03
3
var ip = req.headers['x-forwarded-for'] || req.socket.remoteAddress 
Adam Smaka
  • 5,977
  • 3
  • 50
  • 55
  • thanks the OP asked for the local IP, but i was looking for this not the local IP so thanks. – Takis Nov 18 '21 at 19:21
2

Use:

var os = require('os');
var networkInterfaces = os.networkInterfaces();
var arr = networkInterfaces['Local Area Connection 3']
var ip = arr[1].address;
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Franco Aguilera
  • 617
  • 1
  • 8
  • 25
2

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' } }
Uli Köhler
  • 13,012
  • 16
  • 70
  • 120
2

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);
Facundo Olano
  • 2,492
  • 2
  • 26
  • 32
  • 1
    just want to mention that you can replace `Object.keys(interfaces).reduce(...)` with `Object.values(interfaces).flat()` and it would be the same thing. – kimbaudi Jul 13 '19 at 22:55
2

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.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
TetraDev
  • 16,074
  • 6
  • 60
  • 61
2

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;
Dave Templin
  • 1,764
  • 1
  • 11
  • 5
1

Here is a multi-IP address version of jhurliman's answer:

function getIPAddresses() {

    var ipAddresses = [];

    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) {
                ipAddresses.push(alias.address);
            }
        }
    }
    return ipAddresses;
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
sethpollack
  • 1,348
  • 1
  • 12
  • 13
1

An improvement on the top answer for the following reasons:

  • Code should be as self-explanatory as possible.

  • Enumerating over an array using for...in... should be avoided.

  • for...in... enumeration should be validated to ensure the object's being enumerated over contains the property you're looking for. As JavaScript is loosely typed and the for...in... can be handed any arbitrary object to handle; it's safer to validate the property we're looking for is available.

     var os = require('os'),
         interfaces = os.networkInterfaces(),
         address,
         addresses = [],
         i,
         l,
         interfaceId,
         interfaceArray;
    
     for (interfaceId in interfaces) {
         if (interfaces.hasOwnProperty(interfaceId)) {
             interfaceArray = interfaces[interfaceId];
             l = interfaceArray.length;
    
             for (i = 0; i < l; i += 1) {
    
                 address = interfaceArray[i];
    
                 if (address.family === 'IPv4' && !address.internal) {
                     addresses.push(address.address);
                 }
             }
         }
     }
    
     console.log(addresses);
    
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Chris GW Green
  • 1,145
  • 9
  • 17
1

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];
A T
  • 13,008
  • 21
  • 97
  • 158
  • to make your code more concise, you can eliminate the call to `reduce` and replace the call to `map` with a call to `flatMap`. – kimbaudi Jul 13 '19 at 22:44
1

Some answers here seemed unnecessarily over-complicated to me. Here's a better approach to it using plain Nodejs.

import os from "os";

const machine = os.networkInterfaces()["Ethernet"].map(item => item.family==="IPv4")

console.log(machine.address) //gives 192.168.x.x or whatever your local address is

See documentation: NodeJS - os module: networkInterfaces

Peter Krebs
  • 3,831
  • 2
  • 15
  • 29
  • "unnecessarily over-complicated", but your example supports only the hardcoded "Etherenet" interface. What about WiFi, or "vEtherenet", or any other network interface? – tenbits Dec 11 '22 at 11:52
1

I'm using Node.js 0.6.5:

$ node -v
v0.6.5

Here is what I do:

var util = require('util');
var exec = require('child_process').exec;

function puts(error, stdout, stderr) {
        util.puts(stdout);
}

exec("hostname -i", puts);
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Yc Zhang
  • 174
  • 1
  • 1
  • 12
  • This works with ```hostname -I``` (uppercase i). It returns a list of all assigned IP addresses of the machine. The first IP address is what you need. That IP is the one attached to the current interface that is up. – blueren Sep 06 '18 at 06:26
0

Here's a variation that allows you to get local IP address (tested on Mac and Windows):


var
    // Local IP address that we're trying to calculate
    address
    // Provides a few basic operating-system related utility functions (built-in)
    ,os = require('os')
    // Network interfaces
    ,ifaces = os.networkInterfaces();


// Iterate over interfaces ...
for (var dev in ifaces) {

    // ... and find the one that matches the criteria
    var iface = ifaces[dev].filter(function(details) {
        return details.family === 'IPv4' && details.internal === false;
    });

    if(iface.length > 0)
        address = iface[0].address;
}

// Print the result
console.log(address); // 10.25.10.147
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
0

The bigger question is "Why?"

If you need to know the server on which your Node.js instance is listening on, you can use req.hostname.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
ATOzTOA
  • 34,814
  • 22
  • 96
  • 117
  • 3
    Maybe you have a script that should perform specific actions only if it's running on the 'live' server but not if the server has been imaged and restored to a new server instance. The local IP address might be the only way for the server to tell whether it's the original or a copy. – Molomby Apr 30 '16 at 14:15
  • so many requirements will be there for getting the IP. for example, autoscaling as a cluster – Sreeraj Nov 11 '16 at 05:38
0

The accepted answer is asynchronous. I wanted a synchronous version:

var os = require('os');
var ifaces = os.networkInterfaces();

console.log(JSON.stringify(ifaces, null, 4));

for (var iface in ifaces) {
  var iface = ifaces[iface];
  for (var alias in iface) {
    var alias = iface[alias];

    console.log(JSON.stringify(alias, null, 4));

    if ('IPv4' !== alias.family || alias.internal !== false) {
      debug("skip over internal (i.e. 127.0.0.1) and non-IPv4 addresses");
      continue;
    }
    console.log("Found IP address: " + alias.address);
    return alias.address;
  }
}
return false;
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Simon Hutchison
  • 2,949
  • 1
  • 33
  • 32
0
import os from "os";

const networkAddresses = Object.values(os.networkInterfaces())
  .flat()
  .reduce(
    (result: string[], networkInterface) =>
      networkInterface?.family === "IPv4"
        ? [...result, networkInterface.address]
        : result,
    []
  );
WynandB
  • 1,377
  • 15
  • 16
0

const { networkInterfaces } = require('os')

const nets = networkInterfaces() const address = nets['Wi-Fi'][1].address

climax
  • 1
  • 1
-2

Using internal-ip:

const internalIp = require("internal-ip")

console.log(internalIp.v4.sync())
Richie Bendall
  • 7,738
  • 4
  • 38
  • 58
-7

If you dont want to install dependencies and are running a *nix system you can do:

hostname -I

And you'll get all the addresses for the host, you can use that string in node:

const exec = require('child_process').exec;
let cmd = "hostname -I";
exec(cmd, function(error, stdout, stderr)
{
  console.log(stdout + error + stderr);
});

Is a one liner and you don't need other libraries like 'os' or 'node-ip' that may add accidental complexity to your code.

hostname -h

Is also your friend ;-)

Hope it helps!

lucss
  • 61
  • 3