npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

node-ip-ts

v1.2.3

Published

Modern TypeScript IP address utility library — ESM, CJS, and browser ready

Downloads

531

Readme

  ___ ____       _____ ____
 |_ _|  _ \     |_   _/ ___|
  | || |_) |_____| | \___ \
  | ||  __/_____| |  ___) |
 |___|_|        |_| |____/

A modern, type-safe IP address utility library for Node.js

node-ip-ts

npm version npm downloads license

TypeScript zero dependencies

Snyk Security Socket Security

node-ip-ts is a full TypeScript rewrite of the popular ip package —
rebuilt from the ground up with strict types, ES Modules, and zero external dependencies.

Installation · Quick Start · API Reference · Contributing


Why node-ip-ts?

The original ip package has millions of weekly downloads but ships no TypeScript types and only supports CommonJS. node-ip-ts solves that:

| | ip | node-ip-ts | |---|:---:|:---:| | TypeScript support | ❌ | ✅ | | ES Module support | ❌ | ✅ | | CommonJS support | ✅ | ✅ | | Type declarations | ❌ | ✅ | | Strict null checks | ❌ | ✅ | | External dependencies | 0 | 0 | | API compatibility | — | ✅ drop-in |


Browser Compatibility

All functions except address() work in both Node.js and browser/bundler environments (Vite, webpack, esbuild, etc.).

| Function | Node.js | Browser | |---|:---:|:---:| | All IP/subnet/bitwise functions | ✅ | ✅ | | loopback() | ✅ | ✅ | | address() | ✅ | ❌ (uses os module) |

If you need an IP in a browser context, obtain it server-side and pass it to the client, or use loopback() as a fallback.


Installation

# npm
npm install node-ip-ts

# pnpm
pnpm add node-ip-ts

# yarn
yarn add node-ip-ts

Requirements: Node.js ≥ 16


Quick Start

ESM / TypeScript

import * as ip from 'node-ip-ts';

// Address classification
ip.isPrivate('192.168.1.1');   // true
ip.isPublic('8.8.8.8');        // true
ip.isLoopback('127.0.0.1');    // true

// Subnet operations
ip.cidr('192.168.1.134/26');   // '192.168.1.128'
const subnet = ip.cidrSubnet('192.168.1.134/26');
subnet.contains('192.168.1.180');  // true

// Conversion
ip.toLong('255.255.255.255');  // 4294967295
ip.fromLong(4294967295);       // '255.255.255.255'

Named imports (tree-shakeable)

import { isPrivate, cidrSubnet, toLong } from 'node-ip-ts';

CommonJS

const ip = require('node-ip-ts');
ip.isPrivate('10.0.0.1'); // true

API Reference

Address Classification

isPrivate(addr: string): boolean

Returns true if the address falls within any private/reserved range:

  • 10.0.0.0/8 — RFC 1918
  • 172.16.0.0/12 — RFC 1918
  • 192.168.0.0/16 — RFC 1918
  • 169.254.0.0/16 — link-local
  • fc00::/7 — IPv6 ULA
  • fe80::/10 — IPv6 link-local
  • ::1, :: — loopback
ip.isPrivate('192.168.0.1');           // true
ip.isPrivate('10.0.0.1');              // true
ip.isPrivate('fd12:3456:789a:1::1');   // true  (IPv6 ULA)
ip.isPrivate('::ffff:192.168.0.1');    // true  (IPv4-mapped IPv6)
ip.isPrivate('8.8.8.8');               // false

isPublic(addr: string): boolean

Inverse of isPrivate. Returns true for publicly routable addresses.

ip.isPublic('1.1.1.1');      // true
ip.isPublic('10.0.0.1');     // false

isLoopback(addr: string): boolean

Returns true for loopback addresses. Supports dotted-decimal, octal, hexadecimal, and long-integer notation.

ip.isLoopback('127.0.0.1');    // true
ip.isLoopback('::1');          // true
ip.isLoopback('0x7f.0.0.1');   // true  (hex notation)
ip.isLoopback('0177.0.0.1');   // true  (octal notation)
ip.isLoopback('2130706433');   // true  (integer notation)
ip.isLoopback('8.8.8.8');      // false

isV4Format(ip: string): boolean

ip.isV4Format('192.168.0.1');  // true
ip.isV4Format('::1');          // false

isV6Format(ip: string): boolean

ip.isV6Format('::1');                   // true
ip.isV6Format('::ffff:192.168.0.1');    // true
ip.isV6Format('192.168.0.1');           // false

Subnet & CIDR

cidr(cidrString: string): string

Returns the network address for a given CIDR string.

ip.cidr('192.168.1.134/26');        // '192.168.1.128'
ip.cidr('2607:f0d0:1002:51::4/56'); // '2607:f0d0:1002::'

cidrSubnet(cidrString: string): SubnetInfo

Returns a full SubnetInfo object for a given CIDR string.

const s = ip.cidrSubnet('192.168.1.134/26');

s.networkAddress;    // '192.168.1.128'
s.firstAddress;      // '192.168.1.129'
s.lastAddress;       // '192.168.1.190'
s.broadcastAddress;  // '192.168.1.191'
s.subnetMask;        // '255.255.255.192'
s.subnetMaskLength;  // 26
s.numHosts;          // 62
s.length;            // 64
s.contains('192.168.1.150'); // true
s.contains('192.168.1.200'); // false

subnet(addr: string, mask: string): SubnetInfo

Same as cidrSubnet but takes address and mask separately.

const s = ip.subnet('192.168.1.134', '255.255.255.192');

mask(addr: string, mask: string): string

Applies a subnet mask to an address via bitwise AND.

ip.mask('192.168.1.134', '255.255.255.0');  // '192.168.1.0'
ip.mask('192.168.1.134', '::ffff:ff00');    // '::ffff:c0a8:100'

fromPrefixLen(prefixlen: number, family?: string | number): string

Converts a prefix length to a subnet mask string.

ip.fromPrefixLen(24);         // '255.255.255.0'
ip.fromPrefixLen(64);         // 'ffff:ffff:ffff:ffff::'  (auto-detects IPv6)
ip.fromPrefixLen(24, 'ipv6'); // 'ffff:ff00::'

Bitwise Operations

not(addr: string): string

Bitwise NOT — useful for computing wildcard masks.

ip.not('255.255.255.0');  // '0.0.0.255'

or(a: string, b: string): string

Bitwise OR. Supports same-protocol and mixed IPv4/IPv6 inputs.

ip.or('0.0.0.255', '192.168.1.10');           // '192.168.1.255'
ip.or('::ff', '::abcd:dcba:abcd:dcba');        // '::abcd:dcba:abcd:dcff'
ip.or('0.0.0.255', '::abcd:dcba:abcd:dcba');   // '::abcd:dcba:abcd:dcff'

isEqual(a: string, b: string): boolean

Deep equality check, IPv4/IPv6 aware (e.g. 127.0.0.1 equals ::ffff:7f00:1).

ip.isEqual('127.0.0.1', '::ffff:127.0.0.1');  // true
ip.isEqual('127.0.0.1', '::7f00:1');           // true
ip.isEqual('127.0.0.1', '::7f00:2');           // false

Buffer Conversion

toBuffer(ip: string, buff?: Buffer, offset?: number): Buffer

Converts an IP string to a raw Buffer (4 bytes for IPv4, 16 for IPv6). Optionally writes into an existing buffer at a given offset.

ip.toBuffer('127.0.0.1');
// <Buffer 7f 00 00 01>

const buf = Buffer.alloc(128);
ip.toBuffer('127.0.0.1', buf, 64);
// writes 4 bytes into buf at offset 64

toString(buff: Buffer, offset?: number, length?: number): string

Converts a Buffer back to an IP address string.

ip.toString(Buffer.from('7f000001', 'hex'));  // '127.0.0.1'
ip.toString(buf, 64, 4);                      // '127.0.0.1'

Long Integer Conversion

toLong(ip: string): number

Converts a dotted-decimal IPv4 address to an unsigned 32-bit integer.

ip.toLong('127.0.0.1');        // 2130706433
ip.toLong('255.255.255.255');  // 4294967295

fromLong(ipl: number): string

Converts an unsigned 32-bit integer back to dotted-decimal.

ip.fromLong(2130706433);  // '127.0.0.1'
ip.fromLong(4294967295);  // '255.255.255.255'

normalizeToLong(addr: string): number

Normalizes an IPv4 address in any notation (decimal, octal, hex, compact) to an unsigned long. Returns -1 on invalid input.

ip.normalizeToLong('127.0.0.1');       // 2130706433  (standard)
ip.normalizeToLong('0x7f.0x0.0x0.1'); // 2130706433  (hex)
ip.normalizeToLong('0177.0.0.01');     // 2130706433  (octal)
ip.normalizeToLong('0x7f000001');      // 2130706433  (single hex)
ip.normalizeToLong('127.1');           // 2130706433  (compact)
ip.normalizeToLong('256.0.0.1');       // -1          (invalid)

Network Interface

address(name?: string, family?: string | number): string

⚠️ Node.js only. This function uses the os module which is not available in browsers.
Calling it in a browser environment will throw a descriptive error. All other functions work in both environments.

Returns an IP address from the current machine's network interfaces.

ip.address();             // first private IPv4 address, e.g. '192.168.1.42'
ip.address('public');     // first public IPv4 address
ip.address('private');    // first private IPv4 address
ip.address('eth0');       // first IPv4 address on eth0
ip.address('eth0', 6);   // first IPv6 address on eth0

Falls back to loopback() if no matching interface is found.

loopback(family?: string | number): string

Returns the loopback address for the given IP family.

ip.loopback();       // '127.0.0.1'
ip.loopback('ipv4'); // '127.0.0.1'
ip.loopback('ipv6'); // 'fe80::1'

Types

import type { IPFamily, SubnetInfo } from 'node-ip-ts';

type IPFamily = 'ipv4' | 'ipv6';

interface SubnetInfo {
  networkAddress: string;
  firstAddress: string;
  lastAddress: string;
  broadcastAddress: string;
  subnetMask: string;
  subnetMaskLength: number;
  numHosts: number;
  length: number;
  contains(other: string): boolean;
}

Project Structure

node-ip-ts/
├── src/
│   └── index.ts          # Single source file — all named exports
├── dist/
│   ├── esm/              # ES Module build (.js + .js.map)
│   ├── cjs/              # CommonJS build (.js + .js.map)
│   └── types/            # Type declarations (.d.ts + .d.ts.map)
├── __tests__/
│   └── ip.test.ts        # Jest test suite
├── tsconfig.esm.json
├── tsconfig.cjs.json
├── tsconfig.types.json
└── package.json

Contributing

Contributions are welcome! Here's how to get started:

# Clone the repo
git clone https://github.com/denycode-dev/ip-ts.git
cd node-ip-ts

# Install dependencies
npm install

# Run tests
npm test

# Build
npm run build

Guidelines

  • All changes must pass the existing test suite (npm test)
  • New features must include corresponding tests
  • Code must pass TypeScript strict mode
  • Keep zero external runtime dependencies

Reporting Issues

Please open an issue with a minimal reproduction case.


Migration from ip

node-ip-ts is designed to be a drop-in replacement. Simply swap your import:

- const ip = require('ip');
+ const ip = require('node-ip-ts');

Or for TypeScript / ESM:

import * as ip from 'node-ip-ts';

All function names and behaviours are identical to the original library.


License

MIT © Deni Irawan Nugraha