yojimbo87
yojimbo87

Reputation: 68403

Get local IP address in Node.js

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?

Upvotes: 449

Views: 624858

Answers (30)

Oleg Kolmak
Oleg Kolmak

Reputation: 1

const networkInterfaces = {
  lo: [
    { address: '127.0.0.1', family: 'IPv4' },
    { address: '::1', family: 'IPv6' }
  ],   
  eth0: [
    { address: '192.168.1.182', family: 'IPv4' },
    { address: 'fe80::8c1c:f33d:a36:a5f7', family: 'IPv6' }
  ]
};

const ipv4Addresses = Object.entries(networkInterfaces)  
  .flatMap(([key, interfaces]) =>
    interfaces
      .filter(iface => iface.family === 'IPv4')
      .map(iface => `${key} : ${iface.address}`)   
  );

console.log(ipv4Addresses); // ['lo : 127.0.0.1', 'eth0 : 192.168.1.182']

Upvotes: 0

Ali Khamis
Ali Khamis

Reputation: 1

Import the networkInterfaces function from the os module

const { networkInterfaces } = require('os')

This function provides details about the network interfaces on the machine

Retrieve the network interfaces

const nets = networkInterfaces();

This returns an object where the keys are interface names (e.g., 'Wi-Fi', 'eth0') and the values are arrays of network details.

Access the IP address of the 'Wi-Fi' network interface

const address = nets['Wi-Fi'][1].address;

This accesses the IP address of the second entry (index 1) in the array for the 'Wi-Fi' interface, which usually represents the IPv4 address.

Example Structure of `networkInterfaces()`

{
  'Wi-Fi': [
    {
      address: 'fe80::1c3d:57ff:fe89:1234', // IPv6
    },
    {
      address: '192.168.1.100', // IPv4
    }
  ]
}
``

Upvotes: 0

Xedecimal
Xedecimal

Reputation: 3223

Here's what I use.

const dns = require('node:dns');
const os = require('node:os');

const options = { family: 4 };

dns.lookup(os.hostname(), options, (err, addr) => {
  if (err) {
    console.error(err);
  } else {
    console.log(`IPv4 address: ${addr}`);
  }
});

This will return your first network interface's IPv4 address. It might also have an IPv6, so in order to get "whatever is listed first" you can use family:0 (or don't pass any options at all) or to explicitly get the IPv6, use family:6 as option instead.

Upvotes: 261

Youssef Egla
Youssef Egla

Reputation: 1601

I assume by local you mean the IP address of the machine on the local network, If that's the case we can use UDP protocol to resolve the IP address.

import udp from "dgram"

const soc = udp.createSocket("udp4")
soc.connect(80, "8.8.8.8", () => {
  console.log(soc.address()) // {address: '192.168.x.x', family: 'IPv4', port: ...}
})

Upvotes: 0

Kaz-LA
Kaz-LA

Reputation: 226

Here's a better working solution (node v18.1.0):

  function getLocalIP() {
      const os = require("os");
      const networkInterfaces = os.networkInterfaces();
      for (const name of Object.keys(networkInterfaces)) {
        for (const net of networkInterfaces[name]) {
          if (net.family == 4 && !net.internal) return net.address;
        }
      }
    }

Upvotes: 0

WynandB
WynandB

Reputation: 1427

import os from "os";

const networkAddresses = Object.values(os.networkInterfaces())
  .flat()
  .reduce(
    (result: string[], networkInterface) =>
      networkInterface?.family === "IPv4"
        ? [...result, networkInterface.address]
        : result,
    []
  );

Upvotes: 1

SimoAmi
SimoAmi

Reputation: 2006

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';
}

Upvotes: 9

nodyou
nodyou

Reputation: 5950

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"

Upvotes: 591

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

Upvotes: 1

KARTHIKEYAN.A
KARTHIKEYAN.A

Reputation: 20118

Use the npm ip module:

var ip = require('ip');

console.log(ip.address());

> '192.168.0.117'

Upvotes: 43

Adam Smaka
Adam Smaka

Reputation: 6403

var ip = req.headers['x-forwarded-for'] || req.socket.remoteAddress 

Upvotes: 3

MK.
MK.

Reputation: 842

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

Upvotes: 16

lucss
lucss

Reputation: 61

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!

Upvotes: -7

Sy Le
Sy Le

Reputation: 89

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);
    """
}

Upvotes: 8

TetraDev
TetraDev

Reputation: 17124

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.

Upvotes: 2

Gokul
Gokul

Reputation: 1141

Install a module called ip like:

npm install ip

Then use this code:

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

Upvotes: 42

Tarandeep Singh
Tarandeep Singh

Reputation: 1390

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.

Upvotes: 7

Simon Hutchison
Simon Hutchison

Reputation: 3035

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;

Upvotes: 0

ATOzTOA
ATOzTOA

Reputation: 36000

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.

Upvotes: 0

Soyoes
Soyoes

Reputation: 940

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']

Upvotes: 7

user1760680
user1760680

Reputation: 31

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);

Upvotes: 3

vault
vault

Reputation: 4087

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;

Upvotes: 12

Franco Aguilera
Franco Aguilera

Reputation: 670

Use:

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

Upvotes: 2

origin1tech
origin1tech

Reputation: 749

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;
}

Upvotes: 3

nwinkler
nwinkler

Reputation: 54477

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.

Upvotes: 3

Chris GW Green
Chris GW Green

Reputation: 1213

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);
    

Upvotes: 1

Krizalys
Krizalys

Reputation: 121

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:

Upvotes: 3

Sviatoslav Zalishchuk
Sviatoslav Zalishchuk

Reputation: 739

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

Upvotes: 0

sethpollack
sethpollack

Reputation: 1358

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;
}

Upvotes: 1

KyleFarris
KyleFarris

Reputation: 17548

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;

Upvotes: 5

Related Questions