HTTP/3, HTTP/2, and raw QUIC server/client package for Node.js 24+, powered by Rust + quiche.
Features
- HTTP/3 server and client over QUIC/UDP
- HTTP/2 fallback over TLS/TCP on the same listener
- Raw QUIC: bidirectional streams, datagrams, session resumption, custom ALPN
- Explicit runtime selection:
fast,portable, orauto - Platform-native I/O: kqueue (macOS), io_uring (Linux fast path),
poll(Linux portable path) - WASM runtime (
runtimeMode: 'wasm') for HTTP/3 and raw QUIC clients, plus a Node-only WASM server — no native.nodeaddon required, and confirmed running inside real Cloudflare workerd - fetch/SSE/EventSource adapters
- Express compatibility via
@currentspace/http3/express
Install
npm install @currentspace/http3
Prebuilt native binaries are currently published for Linux x64/arm64 (glibc)
and macOS arm64. Other platforms may fall back to local native compilation; see
docs/SUPPORT_MATRIX.md.
Quick server example
import { createSecureServer } from '@currentspace/http3'; const server = createSecureServer({ key: process.env.TLS_KEY_PEM, cert: process.env.TLS_CERT_PEM, }, (stream, headers) => { stream.respond({ ':status': '200', 'content-type': 'text/plain' }); stream.end(`hello ${String(headers[':path'] ?? '/')}`); }); server.listen(443, '0.0.0.0');
Quick client example
import { connectAsync } from '@currentspace/http3'; const session = await connectAsync('example.com:443'); const stream = session.request({ ':method': 'GET', ':path': '/', ':authority': 'example.com', ':scheme': 'https', }, { endStream: true });
Runtime modes
Every QUIC-capable API accepts:
runtimeMode: 'auto' | 'fast' | 'portable'fallbackPolicy: 'error' | 'warn-and-fallback'onRuntimeEvent(info)
Returned client sessions and server objects expose runtimeInfo, and auto
fallback also emits a process warning with code WARN_HTTP3_RUNTIME_FALLBACK.
import { connectQuicAsync } from '@currentspace/http3'; const session = await connectQuicAsync('https://sfu:9080', { alpn: ['sfu-repl'], rejectUnauthorized: false, runtimeMode: 'auto', fallbackPolicy: 'warn-and-fallback', }); console.log(session.runtimeInfo);
See docs/RUNTIME_MODES.md for the deployment matrix,
capability requirements, Docker guidance, topology policy, and the raw endpoint
contract.
Client topology is now explicit in the implementation:
- raw QUIC fast clients share one worker and one local UDP port per bind family
- H3 fast clients share one worker and one local UDP port per bind family
- macOS portable mode keeps the same shared client-worker ownership model on
top of
kqueue - QUIC and H3 servers remain one-worker-per-port architectures
Use the built-in benchmarks to inspect both runtime selection and internal reactor counters:
npm run bench:quic -- --profile smoke npm run bench:h3 -- --profile smoke
WASM runtime
runtimeMode: 'wasm' runs the client (HTTP/3 or raw QUIC) entirely on a
wasm32-wasip1 build of the same quiche + BoringSSL protocol core, with no
native .node addon in the process:
import { connectAsync } from '@currentspace/http3'; const session = await connectAsync('example.com:443', { runtimeMode: 'wasm' });
The server side (Http3SecureServer.listen() / QuicServer.listen()) also
supports runtimeMode: 'wasm', Node-only. The client build has additionally
been verified running inside real Cloudflare workerd — see
examples/workerd-client; the only
remaining blocker to a real workerd deployment is that Workers has no outbound
UDP client socket API yet (cloudflare/workerd#4463).
See docs/WASM_RUNTIME.md for the full usage guide
and current Node/workerd support matrix, and
docs/WASM_CLIENT_PLAN.md for the design.
Raw QUIC mTLS
- Raw QUIC clients can use mTLS through the stable public
certandkeyoptions onconnectQuic()andconnectQuicAsync(). - Raw QUIC servers support explicit client certificate policy with
clientAuth, defaulting torequirewhen a verificationcais configured. - Raw QUIC server sessions expose the verified peer certificate so applications can inspect or pin exact client certificates with Node's
X509CertificateAPI.
See CHANGELOG.md for release notes and
docs/RELEASE_EVIDENCE.md for the current
release's audit ledger and caveats.
Quick QUIC server
import { createQuicServer } from '@currentspace/http3'; const server = createQuicServer({ key: process.env.TLS_KEY_PEM, cert: process.env.TLS_CERT_PEM, }); server.on('session', (session) => { session.on('stream', (stream) => { stream.pipe(stream); // echo }); }); await server.listen(4433, '0.0.0.0');
Quick QUIC client
import { connectQuicAsync } from '@currentspace/http3'; const session = await connectQuicAsync('127.0.0.1:4433', { rejectUnauthorized: false, }); const stream = session.openStream(); stream.end(Buffer.from('hello QUIC')); const chunks: Buffer[] = []; stream.on('data', (c) => chunks.push(c)); stream.on('end', () => console.log(Buffer.concat(chunks).toString()));
Compatibility surfaces
@currentspace/http3- canonical API.@currentspace/http3/parity- http2-style aliases for migrations.@currentspace/http3/h3- HTTP/3-specific extension namespace.
Examples
Start Here
- Quickstart
- Runtime modes and deployment matrix
- WASM runtime guide
- Support matrix
- Configuration options reference
- Error handling guide
- Changelog
Deployment and Operations
- QUIC guide
- Production docs index
- HTTP/2 parity matrix
- ECS/Fargate deployment
- AWS NLB QUIC passthrough
- Session ticket keys across instances