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

@bybrave/request-ip2

v4.0.0

Published

Maintained fork of request-ip — get the client IP from a request, now with secure X-Forwarded-For parsing, dual ESM+CJS, built-in TypeScript types and 0 dependencies

Downloads

27

Readme

@bybrave/request-ip2

CI npm

Maintained fork of request-ip — retrieve the client IP address from an incoming HTTP request — with secure X-Forwarded-For parsing, dual ESM + CommonJS, built-in TypeScript types and 0 dependencies.

The original package has ~10.9M downloads/month and no release since 2022. Its default X-Forwarded-For handling trusts the left-most (client-controlled) IP, which is spoofable — the single most-upvoted issue on the repo. This fork keeps the original behaviour byte-for-byte by default and adds opt-in options to resolve the IP safely.

npm install @bybrave/request-ip2
// CommonJS — drop-in
const { getClientIp, mw } = require('@bybrave/request-ip2');

// ESM — named imports
import { getClientIp, mw } from '@bybrave/request-ip2';

// TypeScript types built in — no @types/request-ip needed

Secure by option, compatible by default

getClientIp(req) with no options behaves exactly like [email protected] (verified byte-for-byte with golden tests). The security fixes are opt-in via a second argument, so upgrading never changes behaviour silently:

// Attacker sends: X-Forwarded-For: 1.2.3.4, <real-ip>
// Your proxy appends the real IP on the right.

getClientIp(req);                    // '1.2.3.4'    — spoofable, original behaviour
getClientIp(req, { proxyCount: 1 }); // real client  — trust only your own proxy

proxyCount is the number of trusted reverse proxies in front of your app. The client IP is taken as the Nth entry from the right of the chain — the part a client cannot forge — instead of the spoofable left-most value.

// Behind Cloudflare — trust CF-Connecting-IP over the (proxy-rewritten) XFF:
getClientIp(req, { headers: ['cf-connecting-ip', 'x-forwarded-for'] });

// Drop private / loopback / link-local addresses while resolving:
getClientIp(req, { filterPrivate: true });

// Combine them:
getClientIp(req, { proxyCount: 2, filterPrivate: true });

Fixes over [email protected]

| Fixed | Original issue | |---|---| | X-Forwarded-For trusts the spoofable left-most IP → opt-in proxyCount for secure resolution | #25 (16 👍) | | Fixed header priority can't prefer CF-Connecting-IP behind Cloudflare → opt-in headers order | #48 (7 👍), #75 | | No way to restrict which headers are trusted → headers acts as a whitelist | #26 | | Private / loopback IPs in X-Forwarded-For returned as the client → opt-in filterPrivate | #24 | | req.connection triggers Fastify FSTDEP005 deprecation warning → prefer req.socket | #86 | | Broken published dist (missing ./is) → clean, verified package, 0 deps | #65 | | No built-in types (separate @types/request-ip, ~2.5M/month) → bundled index.d.ts, incl. getClientIpFromXForwardedFor | #54 | | CommonJS only, no import support → dual ESM + CJS | — |

The "first vs last IP in X-Forwarded-For" debate (#57, #60) is by design resolved through proxyCount, not by flipping the default — the correct answer depends on how many trusted proxies you run.

Migrating from request-ip

- const requestIp = require('request-ip');
+ const requestIp = require('@bybrave/request-ip2');

The API is identical. Nothing changes until you pass options. When you're ready to harden IP resolution, set proxyCount to the number of proxies in front of your app (e.g. 1 behind a single load balancer):

- const ip = requestIp.getClientIp(req);
+ const ip = requestIp.getClientIp(req, { proxyCount: 1 });

If you use the middleware, the same options are accepted:

app.use(requestIp.mw({ proxyCount: 1 }));
// req.clientIp is now resolved securely

API

getClientIp(req, options?)

Returns the client IP as a string, or null if none could be determined. Reads proxy headers first (in priority order), then req.socket / req.connection, req.info (hapi), AWS Lambda requestContext.identity.sourceIp, and recurses into req.raw (Fastify).

Options (all opt-in):

| Option | Type | Effect | |---|---|---| | headers | string[] | Custom proxy-header priority list, replacing the default order. Also acts as a whitelist. | | proxyCount | number | Number of trusted reverse proxies. Selects the client IP as the Nth entry from the right of X-Forwarded-For. | | filterPrivate | boolean | Skip private / loopback / link-local addresses when resolving. |

getClientIpFromXForwardedFor(value, options?)

Parses a raw X-Forwarded-For header value into a single IP. Accepts the same proxyCount and filterPrivate options.

mw(options?)

Express/Connect middleware that attaches the resolved IP to the request. Accepts every getClientIp option plus attributeName (default clientIp).

Support

If this package saves you time, you can support maintenance:

Ko-fi Bitcoin

Bitcoin (BTC): bc1q37557q5jpeaxqydzwvf3jgj7zhnfpn2td3q40q

Credits & license

MIT. Based on request-ip by Petar Bojinov.