
node-reqwest
Node.js bindings for reqwest — a Rust HTTP client library.
A drop-in replacement for undici with HTTP/2 multiplexing that
decisively outperforms it, system proxy, trusted system CA certificates,
and Electron compatibility out of the box.
Implements the full undici.Dispatcher interface — including its
error classes — and is verified against the same web-platform tests
that undici uses for standards compliance.
Why node-reqwest?
| DNS resolver | Async pure-Rust (hickory-dns) | C (c-ares) — crashes Electron on Windows for nonexistent domains |
| System CA certificates | Built-in | Requires win-ca, mac-ca |
| System proxy | Built-in | Not available (complex Electron workaround) |
| SOCKS proxy | Built-in | Not available |
| HTTP/2 | Multiplexed via hyper | Implemented, but materially slower (see benchmarks) |
| TLS | rustls | OpenSSL |
Benchmarks
Throughput vs. undici on the same workload. The conservative number
between two timed runs (with a warm-up run discarded):
| HTTP/1 GET | at parity |
| HTTP/1 POST (stream body) | +5% |
| HTTP/2 GET | +50% |
| HTTP/2 POST (stream body) | +55% |
HTTP/2's multiplexing advantage is decisive — and every real-world
server supports it. HTTP/1 GET, the tightest hot path, lands within
run-to-run noise of undici (mean throughput; p50 favors node-reqwest by
3–7% but tail latency is GC-jittery on both sides).
Reproduce the benchmarks
The benchmark suite lives in packages/node/benchmarks/.
Each scenario starts a loopback HTTP/1 or HTTP/2 server (using
selfsigned for HTTP/2 TLS) and drives 100 parallel dispatches per
iteration via vitest's bench() runner; warm-up dispatches
prime the connection pool and JIT before timed samples.
To reproduce locally:
git clone --recurse-submodules https://github.com/vadimpiven/node_reqwest.git
cd node_reqwest
mise install
pnpm install
pnpm --filter node-reqwest run bench
pnpm run bench builds the Rust addon first (via prebench), then
executes every *.bench.ts file in packages/node/benchmarks/. Each
run prints per-bench hz (ops/sec), latency percentiles, and a
"Nx faster than" summary comparing the two dispatchers.
The README numbers are the conservative result between two consecutive
runs (the worst-for-node-reqwest ratio), with a discarded warm-up run
preceding them. Absolute throughput depends on your machine; the
ratio between the two dispatchers is what's stable across hardware.
Usage
This library provides an Agent that implements the
undici.Dispatcher interface. Use it as a global dispatcher for
fetch or with any undici-compatible API.
import { Agent } from "node-reqwest";
import { setGlobalDispatcher } from "undici";
const agent = new Agent({
allowH2: true,
proxy: "system",
});
setGlobalDispatcher(agent);
const response = await fetch("https://example.com");
Installation safety
This package downloads a precompiled binary during npm install.
GitHub releases for this project are
immutable — once published, release
assets cannot be modified or replaced, ensuring that the binary
you download is the same one that was originally published.
In addition, the postinstall script uses
node-addon-slsa to cryptographically verify that the
binary was built in the same GitHub Actions workflow run as this
npm package, using sigstore provenance attestations
and the GitHub Attestations API.
Installation aborts with a SECURITY error if any check fails.
License
Apache-2.0 OR
MIT