v0.x

QUIC · HTTP/3 · WebTransport

HTTP/3 for Node.js, in pure JavaScript

QUIC, HTTP/3, QPACK and WebTransport — from UDP to your request handler, without OpenSSL or a single native binding.

  • One install. npm install quico — no compiler, no prebuilt binaries.
  • Drop-in API. createServer and request as in node:https; Express, Fastify and Koa work.
  • Debuggable. Every byte of the handshake is JavaScript you can step through.
npm install quico

Tested against Google, Cloudflare, Facebook, Microsoft and nginx.

npm install quico
added 1 package in 2s
node client.js
✓ QUIC connected · cloudflare-quic.com:443
✓ TLS 1.3 · X25519 · AES-128-GCM-SHA256
Status: 200 · Protocol: h3 · 125 KB
QUIC · 1-RTT · cloudflare-quic.com connected
  1. Initial · ClientHelloSNI, ALPN=h3, X25519
  2. Initial · ServerHelloAES-128-GCM-SHA256
  3. Handshake · Cert + CVrsa_pss_rsae_sha256
  4. Handshake · FinishedHKDF-Expand-Label
  5. Handshake · FinishedRFC 9001 §4.1.1
  6. 1-RTT · SETTINGS + HEADERSQPACK · GET /
  7. 1-RTT · 200 OK + body125 KB · FIN
rtt: 22mscipher: AES-128-GCMgroup: X25519
  • 7+production servers tested
  • 0native bindings
  • RFC 9000QUIC v1, per the RFC
  • httpsthe node:https API

Interop

Talks to the servers you already use

Every big QUIC deployment reads the RFCs a little differently. These are the ones QUICO is tested against.

Features

The whole stack, in one package

Transport, crypto, HTTP/3 and WebTransport — written from the RFCs, readable end to end.

01 · Transport

QUIC v1

Connection IDs, flow control, key updates and handshake timeouts — RFC 9000 and RFC 9001.

RFC 9000RFC 9001
02 · Crypto

TLS 1.3 via LemonTLS

A pure-JavaScript TLS 1.3 handshake, AES-GCM cipher suites and HelloRetryRequest — no OpenSSL.

X25519P-256P-384AES-GCM
03 · HTTP/3

HTTP/3 + QPACK

Requests multiplexed over one connection, headers compressed with QPACK.

RFC 9114RFC 9204
04 · WebTransport

Streams and datagrams

Bidirectional and unidirectional streams plus unreliable datagrams, on the server and in a Node.js client.

RFC 9297WHATWG
05 · API

The node:https API

createServer, request, get, SNICallback — and your framework keeps working.

createServerrequest
06 · Fallback

H3 → H2 → H1

Advertises itself with Alt-Svc and falls back when the other side does not speak HTTP/3.

Alt-Svcpooling

Usage

If you know node:https, you know QUICO

server.js
import quico from 'quico';
import fs from 'node:fs';

const server = quico.createServer({
  key:  fs.readFileSync('server.key'),
  cert: fs.readFileSync('server.crt')
}, (req, res) => {
  res.writeHead(200, { 'content-type': 'text/plain' });
  res.end('Hello from HTTP/3!');
});

server.listen(4433);
// curl --http3 https://localhost:4433
client.js
import quico from 'quico';

quico.request('https://www.google.com/', (res) => {
  console.log('Status:', res.statusCode);
  res.on('data', (chunk) => process.stdout.write(chunk));
});
app.js
import express from 'express';
import quico from 'quico';

const app = express();
app.get('/', (req, res) => res.send('hi'));

// The same Express app, now on HTTP/3.
quico.createServer(tlsOptions, app).listen(4433);
wt-client.js
const wt = new WebTransport('https://localhost:4433/echo');
await wt.ready;

const stream = await wt.createBidirectionalStream();
wt.sendDatagram(Buffer.from('ping'));

Compare

How it compares

What you get from QUICO next to the HTTP options already in Node.js.

Checker

Does your server speak HTTP/3?

Point a QUIC client at a hostname and see what answers: protocol, implementation, cipher and round trip.

Check your server

Type a hostname to see the kind of report the checker gives.

Hostname

Demo: the values are a sample derived from the name you type — no connection is made. The live checker is on the way.

Ship HTTP/3 today

One package, no build step.

npm install quico

Apache 2.0 · no native code · Star it on GitHub