ipaddr.js
ipaddr.js is a lightweight JavaScript library (1.9K minified+gzipped) designed for comprehensive manipulation of both IPv4 and IPv6 addresses. Its current stable version is 2.3.0, and it maintains a steady release cadence for bug fixes and minor improvements. The library functions effectively in both CommonJS (Node.js 10+) and browser environments, shipping with TypeScript types for enhanced development. Key functionalities include validating and parsing IP address strings, matching addresses against CIDR ranges or custom range lists, identifying reserved IP address ranges (e.g., loopback, private), and automatically converting IPv4-mapped IPv6 addresses to their IPv4 equivalents, which is particularly useful for Node.js servers listening on IPv6 sockets. Its primary differentiator is its small footprint and comprehensive set of core IP address utilities without external dependencies.
Common errors
-
Error: Invalid IP address
cause Attempting to parse a malformed or syntactically incorrect IP address string using `ipaddr.parse()` without error handling.fixValidate the input string with `ipaddr.isValid()` before parsing, or wrap `ipaddr.parse()` calls in a `try...catch` block to handle exceptions gracefully. -
TypeError: ipaddr.isValid is not a function
cause Incorrect CommonJS `require` or ES module `import` syntax, leading to the `ipaddr` variable not correctly referencing the default export object.fixFor CommonJS, use `const ipaddr = require('ipaddr.js');`. For ES modules, use `import ipaddr from 'ipaddr.js';`. Do not use named imports like `import { ipaddr } from 'ipaddr.js';`. -
TS2307: Cannot find module 'ipaddr.js' or its corresponding type declarations.
cause TypeScript compiler is unable to locate the type definition files for `ipaddr.js`. While `ipaddr.js` ships with its own types, this can occur in certain project configurations or if an older version is in use.fixEnsure `ipaddr.js` is correctly installed. If the issue persists, verify your `tsconfig.json` paths or consider installing `@types/ipaddr.js` as a dev dependency (though typically not needed for recent versions of `ipaddr.js`).
Warnings
- breaking Version 2.x of `ipaddr.js` requires Node.js version 10 or higher. For applications targeting older Node.js environments (prior to Node.js 10), you must use the `1.x` release series of `ipaddr.js`.
- gotcha The `ipaddr.parse()` method throws an `Error` for syntactically invalid IP address strings. In contrast, `ipaddr.isValid()` and `ipaddr.isValidCIDR()` return a boolean `false` without throwing an exception.
- gotcha The `toString()` method on `IPv4` and `IPv6` objects returns a compact, normalized string representation of the IP address, which may not be identical to the original input string used to create the object. This is by design, as the library normalizes addresses.
- gotcha The `addr.match(range, bits)` method can only compare an address against a CIDR range of the *same IP address family*. Attempting to match an IPv4 address against an IPv6 range (or vice-versa) will result in incorrect behavior or potential runtime errors.
Install
-
npm install ipaddr.js -
yarn add ipaddr.js -
pnpm add ipaddr.js
Imports
- ipaddr
import { ipaddr } from 'ipaddr.js';import ipaddr from 'ipaddr.js';
- ipaddr (CommonJS)
const ipaddr = require('ipaddr.js'); - IPv4, IPv6 (Types)
import { IPv4, IPv6 } from 'ipaddr.js';import type { IPv4, IPv6, Address, Subnet } from 'ipaddr.js';
Quickstart
import ipaddr from 'ipaddr.js';
// --- Validation and Parsing ---
const ipAddressStringV4 = '192.168.1.100';
const ipAddressStringV6 = '2001:0db8:85a3::8a2e:0370:7334';
const invalidIp = '999.999.999.999';
const cidrV4 = '192.168.1.0/24';
const cidrV6 = '2001:db8::/32';
console.log(`Is '${ipAddressStringV4}' valid? ${ipaddr.isValid(ipAddressStringV4)}`);
console.log(`Is '${invalidIp}' valid? ${ipaddr.isValid(invalidIp)}`);
try {
const parsedV4 = ipaddr.parse(ipAddressStringV4);
console.log(`Parsed IPv4: ${parsedV4.toString()} (Kind: ${parsedV4.kind()})`);
const parsedV6 = ipaddr.parse(ipAddressStringV6);
console.log(`Parsed IPv6: ${parsedV6.toString()} (Kind: ${parsedV6.kind()})`);
// Demonstrate process() with an IPv4-mapped IPv6 address
const mappedV4inV6 = '::ffff:192.168.1.100';
const processedAddr = ipaddr.process(mappedV4inV6);
console.log(`Processed '${mappedV4inV6}': ${processedAddr.toString()} (Kind: ${processedAddr.kind()})`);
// --- CIDR Matching ---
console.log(`Is '${cidrV4}' a valid CIDR? ${ipaddr.isValidCIDR(cidrV4)}`);
const ipToMatchV4 = ipaddr.parse('192.168.1.50');
const [rangeV4, bitsV4] = ipaddr.parseCIDR(cidrV4);
console.log(`Does ${ipToMatchV4.toString()} match ${cidrV4}? ${ipToMatchV4.match(rangeV4, bitsV4)}`);
const ipToMatchV6 = ipaddr.parse('2001:db8:ffff::1');
const [rangeV6, bitsV6] = ipaddr.parseCIDR(cidrV6);
console.log(`Does ${ipToMatchV6.toString()} match ${cidrV6}? ${ipToMatchV6.match(rangeV6, bitsV6)}`);
// --- Special Ranges ---
const loopbackV4 = ipaddr.parse('127.0.0.1');
console.log(`'${loopbackV4.toString()}' is a '${loopbackV4.range()}' address.`);
const privateV4 = ipaddr.parse('10.0.0.1');
console.log(`'${privateV4.toString()}' is a '${privateV4.range()}' address.`);
} catch (error: any) {
console.error(`Error parsing IP address: ${error.message}`);
}
// Example of incorrect usage (type mismatch for match)
try {
const ipv4 = ipaddr.parse('192.168.1.1');
const ipv6Range = ipaddr.parse('2001:db8::');
// The .match method expects arguments of the same IP address family.
// Attempting this will not work as expected and might throw a runtime error.
// console.log(ipv4.match(ipv6Range, 16));
} catch (e: any) {
// This catch block would normally handle a TypeError if the match method was called with mismatched types.
// The actual method will silently return false or throw based on its internal logic, highlighting a gotcha.
// For demonstration, we'll just acknowledge the mismatch.
console.warn("Attempted to match IPv4 against IPv6 range. (Expected type mismatch, handled gracefully or via explicit check).");
}