v0.x

WebTransport in Node.js with QUICO

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

WebTransport gives browsers what WebSockets never could: many independent streams over one connection, without head-of-line blocking, plus unreliable datagrams for data that is useless when late — game state, cursor positions, live telemetry.

The server side

A WebTransport session arrives as an HTTP/3 extended CONNECT request. QUICO surfaces it on the familiar request object: streams and datagrams are events.

javascript
server.on('request', (req, res) => {
  req.on('stream', (stream) => stream.pipe(stream));   // echo
  req.on('datagram', (data) => res.sendDatagram(data));
  res.writeHead(200);
});

The client side

The Node.js client follows the browser API, so the same code can run in both places:

javascript
const wt = new WebTransport('https://localhost:4433/echo');
await wt.ready;

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

Datagrams

Datagrams follow RFC 9297 (HTTP Datagrams). They are not retransmitted and not ordered. If one is lost, it is gone — which is exactly what you want for a position update that the next one supersedes.

colocohen

Author of QUICO, LemonTLS and a family of pure-JavaScript network servers.