IP Address

Extract and validate client IP addresses securely with Network module.

Creating a Network Instance

import { Network } from "toolkitify/network";

const network = new Network({
    proxy: "cloudflare",                    // Proxy type or array of proxies.
    trustedProxies: ["10.0.0.0/8"],         // Additional trusted proxy ranges.
    customHeaders: ["X-My-Custom-IP"],      // Custom headers to check first.
    useXForwardedFor: true                  // Use X-Forwarded-For as fallback (default: true).
});

Interfaces

NetworkOptions

ParameterTypeRequiredDescription
proxyProxyType | ProxyType[]NoProxy type(s) to prioritize
trustedProxiesstring[]NoTrusted proxy IPs or CIDR ranges
customHeadersstring[]NoCustom headers to check (highest priority)
useXForwardedForbooleanNoUse X-Forwarded-For as fallback (default: true)

ClientIPResult

PropertyTypeDescription
ipstring | nullThe detected client IP address
source"direct" | "header" | "x-forwarded-for"Source of the IP
headerstring | undefinedHeader name that provided the IP
trustedbooleanWhether the IP came from a trusted source

ProxyType

type ProxyType =
    | "cloudflare" | "aws" | "vercel" | "fastly"
    | "akamai" | "nginx" | "gcp" | "azure"
    | "fly" | "render" | "railway" | "heroku";

getClientIP()

Extracts the real client IP address from a request with full metadata.

const result = network.getClientIP(req);

console.log(result.ip);      // "203.0.113.50"
console.log(result.source);  // "header"
console.log(result.header);  // "cf-connecting-ip"
console.log(result.trusted); // true

Override options per request

const result = network.getClientIP(req, {
    proxy: "aws",  // Override proxy for this call.
    trustedProxies: ["172.16.0.0/12"]
});

extractIP()

Simple helper that returns only the IP string (or null).

const ip = network.extractIP(req);

if (ip) {
    console.log(`Request from: ${ip}`);
}

isLocal()

Checks if an IP address is localhost/loopback. Matches 127.x.x.x, ::1, and localhost.

network.isLocal("127.0.0.1");     // true
network.isLocal("127.0.0.254");   // true
network.isLocal("::1");           // true
network.isLocal("localhost");     // true
network.isLocal("192.168.1.1");   // false
network.isLocal("8.8.8.8");       // false

isPrivate()

Checks if an IP address is private/internal (RFC 1918 ranges).

network.isPrivate("192.168.1.1");   // true  (192.168.0.0/16)
network.isPrivate("10.0.0.5");      // true  (10.0.0.0/8)
network.isPrivate("172.16.0.1");    // true  (172.16.0.0/12)
network.isPrivate("8.8.8.8");       // false (public IP)
network.isPrivate("1.1.1.1");       // false (public IP)

Private IP Ranges

RangeCIDR
10.0.0.0 - 10.255.255.25510.0.0.0/8
172.16.0.0 - 172.31.255.255172.16.0.0/12
192.168.0.0 - 192.168.255.255192.168.0.0/16
127.0.0.0 - 127.255.255.255127.0.0.0/8

isInRange()

Checks if an IP address is within a CIDR range.

network.isInRange("192.168.1.50", "192.168.1.0/24");   // true
network.isInRange("192.168.2.1", "192.168.1.0/24");    // false
network.isInRange("10.0.0.1", "10.0.0.0/8");           // true
network.isInRange("10.0.0.1", "192.168.0.0/16");       // false

normalize()

Normalizes an IP address. Handles IPv4-mapped IPv6 addresses and validates format.

network.normalize("::ffff:192.168.1.1");  // "192.168.1.1"
network.normalize("  8.8.8.8  ");         // "8.8.8.8"
network.normalize("::1");                 // "::1"
network.normalize("invalid");             // null
network.normalize("999.999.999.999");     // null

configure()

Updates the default options for future calls.

// Change proxy configuration.
network.configure({ proxy: "aws" });

// Add trusted proxies.
network.configure({
    trustedProxies: ["10.0.0.0/8", "172.16.0.0/12"]
});

getConfig()

Returns the current configuration.

const config = network.getConfig();
console.log(config.proxy);          // "cloudflare"
console.log(config.trustedProxies); // ["10.0.0.0/8"]

Standalone Functions

You can also use standalone functions without creating an instance:

import { getClientIP, extractClientIP, isLocalIP, isPrivateIP } from "toolkitify/network";

// Get client IP with options.
const result = getClientIP(req, { proxy: "cloudflare" });

// Extract just the IP.
const ip = extractClientIP(req, { proxy: "vercel" });

// Validate IPs.
isLocalIP("127.0.0.1");    // true
isPrivateIP("10.0.0.1");   // true

Full Example

import { Network } from "toolkitify/network";
import express from "express";

const app = express();

// Configure for Cloudflare + internal load balancer.
const network = new Network({
    proxy: ["cloudflare", "nginx"],
    trustedProxies: ["10.0.0.0/8"]
});

// Middleware to attach client IP.
app.use((req, res, next) => {
    const { ip, trusted } = network.getClientIP(req);

    // Skip localhost in development.
    if (network.isLocal(ip)) {
        console.log("Local request, skipping IP logging");
        return next();
    }

    // Log public IPs.
    if (!network.isPrivate(ip)) {
        console.log(`Public IP: ${ip}, Trusted: ${trusted}`);
    }

    req.clientIP = ip;
    next();
});

// Use in rate limiting.
app.get("/api/data", (req, res) => {
    const ip = req.clientIP;
    // ... your logic
});