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

@verifyhash/ip-cidr

v0.1.2

Published

Zero-dependency IPv4 (and basic IPv6) address/CIDR toolkit for Node.js: validate/parse, CIDR math (network, broadcast, first/last host, host count), ip<->integer, and containment.

Readme

ip-cidr

A tiny, zero-dependency IPv4 (and basic IPv6) address/CIDR toolkit for Node.js. It does the boring arithmetic you always end up rewriting: validate an address, parse a CIDR block, ask whether a block contains an IP, and compute the network/broadcast/first/last host and host count of a subnet — plus lossless ip↔integer conversion.

No network access, no runtime dependencies, no servers. Just math on the bits.

Install

npm install @verifyhash/ip-cidr

Published as @verifyhash/ip-cidr; source lives in the verifyhash/libs monorepo. Zero runtime dependencies — you can also vendor the folder directly.

Who it's for

  • Anyone writing allow/deny lists, firewall-ish rules, or geo/ASN buckets who needs a correct contains(cidr, ip) without pulling a dependency tree.
  • Tools and CLIs that display subnet facts (network, broadcast, usable range, host count) for an operator.
  • Code that stores IPs as integers (databases, bitmaps) and needs a reliable round-trip to/from dotted-quad.

Install & usage

Zero runtime dependencies (tests use only built-in assert) — you can also vendor the folder directly. In your project:

const ip = require('@verifyhash/ip-cidr'); // during development: require('./index.js')

// Containment
ip.contains('10.0.0.0/8', '10.1.2.3');      // => true
ip.contains('192.168.1.0/24', '192.168.2.9'); // => false

// Subnet facts
const net = ip.parseCidr('192.168.1.10/24');
net.network;    // '192.168.1.0'
net.broadcast;  // '192.168.1.255'
net.firstHost;  // '192.168.1.1'
net.lastHost;   // '192.168.1.254'
net.hostCount;  // 254   (usable hosts)
net.size;       // 256   (total addresses)

// Address <-> integer (lossless, unsigned 32-bit)
ip.ipv4ToInt('192.168.1.1'); // 3232235777
ip.intToIpv4(3232235777);    // '192.168.1.1'

// Validation / dispatch
ip.isValidIPv4('1.2.3.256'); // false
ip.ipVersion('::1');          // 6
ip.parse('8.8.8.8');          // { version: 4, address: '8.8.8.8', int: 134744072 }

API

IPv4 core

  • isValidIPv4(str) → boolean — strict dotted-quad. Rejects leading zeros (01.2.3.4), out-of-range octets (1.2.3.256), and wrong segment counts.
  • ipv4ToInt(str) → number — unsigned 32-bit integer (throws on invalid).
  • intToIpv4(int) → string — inverse (throws if outside 0 … 4294967295).

IPv6 core

  • isValidIPv6(str) → boolean — supports :: compression and an embedded IPv4 tail (::ffff:192.168.0.1). Zone ids (%eth0) are rejected.
  • ipv6ToBigInt(str) → bigint / bigIntToIpv6(bigint) → string — lossless round-trip via BigInt. bigIntToIpv6 returns the fully expanded (uncompressed) form, e.g. 0:0:0:0:0:0:0:1, not ::1.

Unified

  • ipVersion(str) → 4 | 6 | null
  • parse(str) → { version, address, int } for v4 or { version, address, big } for v6 (throws on invalid).
  • parseCidr(str) → object — see fields below (throws on invalid).
  • contains(cidr, ip) → boolean — throws only if cidr/ip can't be parsed; returns false (never throws) when the two are different address families.

parseCidr result

IPv4 blocks return numeric and string forms:

| field | example (192.168.1.10/24) | notes | |-------|------------------------------|-------| | network / networkInt | 192.168.1.0 / 3232235776 | masked base address | | broadcast / broadcastInt | 192.168.1.255 / … | all-ones host | | firstHost / lastHost | 192.168.1.1 / 192.168.1.254 | usable range | | size | 256 | total addresses in the block | | hostCount | 254 | usable hosts (size − 2, except /31,/32) | | prefix | 24 | |

IPv6 blocks return network, firstHost, lastHost (strings) plus networkBig, firstHostBig, lastHostBig, size, and hostCount as BigInt. There is no broadcast for IPv6 — broadcast is not an IPv6 concept.

/31 and /32 edge cases

/32 is treated as a single usable host (hostCount: 1). /31 follows RFC 3021: both addresses are usable point-to-point endpoints, so hostCount: 2 with no network/broadcast reservation. Wider IPv4 blocks use the conventional size − 2 usable-host count.

IPv6 support scope (honest limits)

IPv6 is partial by design. Fully supported:

  • Validation & parsingisValidIPv6, ipv6ToBigInt, including :: compression and embedded-IPv4 tails.
  • Containmentcontains(cidr, ip) and parseCidr work for v6 using BigInt, so there is no precision loss across the full 128-bit space.

Intentionally not provided for IPv6:

  • No broadcast/first-usable/last-usable reservation semantics (v6 has no broadcast). firstHost/lastHost are just the block's low/high addresses.
  • bigIntToIpv6 emits the expanded form only — it does not produce the RFC 5952 shortest/canonical :: form.
  • No zone identifiers (fe80::1%eth0), no scoped/link-local special handling, no CIDR aggregation/summarization, and no IPv4-mapped normalization beyond parsing the embedded-IPv4 syntax.

If you need full IPv6 canonicalization or aggregation, use a dedicated library. IPv4 is the first-class, fully-featured path here.

Running the tests

One command, no framework (Node's built-in assert):

node test/index.test.js
# or
npm test

The suite covers: containment true/false cases, /31 and /32 edges, network/broadcast math for known blocks, ip↔int round-trips, invalid-input rejection (bad octets, out-of-range masks, malformed strings), and the IPv6 validate/parse/contain paths.

License

MIT — see LICENSE.