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

warproxy

v0.2.0

Published

Local HTTP + SOCKS5 proxy (TCP and UDP: BitTorrent, DHT, DNS...) that routes everything through Cloudflare WARP. One command, no admin rights, Windows / Linux / macOS.

Readme

warproxy

A local HTTP + SOCKS5 proxy on one port that sends everything — TCP and UDP (BitTorrent trackers, DHT, µTP, DNS, games…) — through the Cloudflare WARP tunnel.

  • One command: warproxy start. It registers a free WARP account, fetches the engine and starts.
  • No admin rights, no TUN device, no system-wide VPN. Only the apps you point at the proxy use WARP.
  • Windows, Linux, macOS (x64 and arm64; Alpine/musl too).
  • Default address 127.0.0.1:25344, a port almost nothing else uses.
your app ──HTTP / SOCKS5──▶ 127.0.0.1:25344 ──userspace WireGuard──▶ Cloudflare WARP ──▶ Internet
          (TCP + UDP)              warproxy (sing-box engine)

Install

Requires Node.js 20 or newer.

npm install -g warproxy
warproxy start

The first start downloads the engine (sing-box, ~30 MB, checksum-verified) and registers a free WARP account. Both are cached in the data directory, so later starts take under a second.

Run it in the background instead:

warproxy start --detach
warproxy status
warproxy test        # checks TCP, HTTP proxy and UDP through the tunnel
warproxy stop

Point your software at it

| Software | Setting | | --- | --- | | curl | curl -x socks5h://127.0.0.1:25344 https://www.cloudflare.com/cdn-cgi/trace (look for warp=on) | | Shell tools | export ALL_PROXY=socks5h://127.0.0.1:25344 or HTTPS_PROXY=http://127.0.0.1:25344 | | git | git config --global http.proxy socks5h://127.0.0.1:25344 | | Firefox | Settings → Network → Manual proxy → SOCKS Host 127.0.0.1, port 25344, SOCKS v5, tick Proxy DNS when using SOCKS v5 | | Chrome / Edge | start with --proxy-server="socks5://127.0.0.1:25344" | | qBittorrent | Options → Connection → Proxy Server: type SOCKS5, host 127.0.0.1, port 25344; tick Use proxy for peer connections and hostname lookups |

Use socks5h:// (with the h) wherever the tool offers the choice: domain names are then resolved through WARP instead of by your local resolver.

What goes through, and what doesn't

| Traffic | Supported | | --- | --- | | HTTP, HTTPS, any TCP (HTTP CONNECT, SOCKS4/4a/5) | Yes | | UDP (DNS, DHT, UDP trackers, µTP, QUIC, games…) | Yes, via SOCKS5 UDP ASSOCIATE, full-cone NAT | | UDP through the HTTP proxy | No — HTTP has no UDP; use the SOCKS5 side | | Apps that ignore proxies, or whose proxy support is TCP-only | Not proxied (browsers, for instance, don't send QUIC over SOCKS) | | ICMP / ping | No (not proxyable) | | Incoming connections / port forwarding | No. WARP gives you no public port, so torrent clients can only connect out: fewer peers, little seeding |

Be clear-eyed about what WARP is: destinations see a shared Cloudflare IP instead of yours, and your traffic to the Internet is encrypted from your machine to Cloudflare. It is not an anonymity tool — Cloudflare sees your traffic metadata, some sites challenge or block WARP addresses, and you remain bound by Cloudflare's terms and by the law for what you transfer.

Commands

| Command | | | --- | --- | | warproxy start | Start in the foreground (Ctrl+C stops). Add -d / --detach for the background | | warproxy stop | Stop the background instance | | warproxy restart | Stop, then start with the options you give | | warproxy status | Is it running? (exit code 0 / 1, scriptable) | | warproxy test | End-to-end check: SOCKS5 TCP with proxy-side DNS, HTTP CONNECT, SOCKS5 UDP relay | | warproxy register [--force] | Create or replace the WARP account | | warproxy config | Print the engine configuration (secrets redacted) | | warproxy engine [info\|install\|path] | Inspect or reinstall the engine | | warproxy update [--dry-run] | Install the latest release (--dry-run only reports it) |

Options for start / restart:

| Option | Meaning | | --- | --- | | -p, --port <n> | Port (default 25344, env WARPROXY_PORT) | | -l, --listen <ip> | Bind address (default 127.0.0.1) | | --auth <user:pass> | Require credentials (env WARPROXY_AUTH, or --user + --pass) | | --endpoint-port <n> | WARP UDP port: 2408 (default), or 500 / 1701 / 4500 | | --endpoint <host> | WARP endpoint host (default engage.cloudflareclient.com) | | --log-level <lvl> | trace debug info warn (default) error | | --engine <path> | Use your own sing-box ≥ 1.12 (env WARPROXY_ENGINE) | | --no-check | Skip the tunnel check after startup | | --no-update-check | Don't look for a newer release at launch (env WARPROXY_NO_UPDATE_CHECK=1) |

Updates

When you run warproxy start or restart, it looks at the latest GitHub release of this project and, if there is a newer one, prints a single line:

warproxy: update available: 0.1.0 -> 0.2.0 (run: warproxy update)

Then warproxy update installs it (npm install -g warproxy@<version>); restart a running proxy afterwards with warproxy restart -d. Nothing is ever installed without you asking.

  • The lookup runs in parallel with the startup, is limited to once a day (once an hour after a failure) and never prints an error: offline, rate-limited or behind a firewall, you simply see nothing.
  • It is one anonymous request to api.github.com (GitHub sees your IP and a warproxy/<version> User-Agent, nothing else).
  • Turn it off with --no-update-check or WARPROXY_NO_UPDATE_CHECK=1. It is also skipped when the CI environment variable is set.
  • If update reports that a release "is not on npm yet", it was published on GitHub a moment ago and npm is still receiving it (about a minute): try again shortly.

Security notes

  • It listens on loopback only by default. Note that any local program or user of the machine can then use the proxy; on a shared machine add --auth.
  • --listen 0.0.0.0 exposes the proxy to your network — only do that together with --auth. warproxy warns when you don't.
  • account.json (WireGuard private key, API token) and run/config.json live in the data directory with owner-only permissions on Linux/macOS (the per-user profile on Windows).
  • The engine is a pinned sing-box release: the downloaded bytes are checked against a SHA-256 stored in this package, and only those exact bytes are extracted and installed (a custom --engine binary is, by design, run as-is). There are no install scripts and no runtime dependencies.
  • On shared Unix machines, give the password through the WARPROXY_AUTH environment variable rather than --auth: while a foreground instance runs, command-line arguments are visible to other users in ps.

Troubleshooting

  • "Tunnel check failed" — your network probably blocks UDP 2408. Try warproxy restart -d --endpoint-port 4500 (or 500, 1701). Some corporate networks block WARP entirely.
  • Windows Firewall prompt for warproxy-engine.exe — the proxy itself only listens on loopback, so declining doesn't expose anything; if the tunnel then fails to connect, allow it.
  • Port already in use — pick another: warproxy start --port 31337.
  • GitHub is blocked — host the engine archive on a mirror and set WARPROXY_ENGINE_BASE_URL (the SHA-256 is still enforced), or pass --engine.
  • Logs — warproxy start --log-level info in the foreground; with --detach, see run/engine.log in the data directory.

Environment variables: WARPROXY_HOME (data directory), WARPROXY_PORT, WARPROXY_AUTH, WARPROXY_ENGINE, WARPROXY_ENGINE_BASE_URL, WARPROXY_NO_UPDATE_CHECK=1, WARPROXY_DEBUG=1 (stack traces).

Data directory: %LOCALAPPDATA%\warproxy (Windows), ~/Library/Application Support/warproxy (macOS), ~/.local/share/warproxy (Linux). To uninstall completely: warproxy stop, npm rm -g warproxy, delete that directory.

How it works

warproxy is a thin, dependency-free Node.js wrapper. It registers a WARP device with Cloudflare's consumer API (the same one the mobile apps and tools like wgcf use), writes a sing-box configuration — a mixed inbound (HTTP + SOCKS) wired to a userspace WireGuard endpoint — and supervises the engine process. Domain names are resolved inside the tunnel (1.1.1.1 through WARP); only the WARP endpoint's own hostname uses your local resolver.

The registration API is unofficial and Cloudflare may change it; if registration starts failing, please open an issue.

Development

npm test                          # unit tests, offline
WARPROXY_E2E=1 npm test           # + live test against real Cloudflare WARP
npm run update-engine [version]   # pin a newer sing-box release (rewrites src/engine-manifest.json)
npm run check-engine              # make sure that engine accepts our generated configuration

Releasing

Publishing a GitHub release publishes the package to npm (release.yml), and the same release is what users are told about by the update check:

npm version minor                           # bumps package.json and creates the git tag vX.Y.Z
git push --follow-tags
gh release create vX.Y.Z --generate-notes   # triggers the workflow: tests, then npm publish

The workflow refuses a release whose tag differs from package.json, runs the tests and npm run check-engine, then publishes (a GitHub pre-release goes to the npm tag next). It uses npm trusted publishing, so no token is stored in the repository. One-time setup on npmjs.com: package warproxy → Settings → Trusted Publisher → GitHub Actions → user ajoly21, repository warproxy, workflow release.yml. Actions → Release → Run workflow does a dry run of everything without publishing.

The repository must be public for users to see releases (the API answers 404 for a private repository, and the check then stays silent); npm build provenance also needs a public repository.

License

MIT for this package. The sing-box engine is downloaded at runtime from its official releases and is licensed separately (GPL-3.0-or-later); it is not bundled. Cloudflare and WARP are trademarks of Cloudflare, Inc.; this project is not affiliated with or endorsed by Cloudflare.