QUIC, in pure Zig
An IETF QUIC transport written from scratch in Zig — QUIC v1 and v2,
pure-Zig TLS 1.3 with 0-RTT and post-quantum key exchange, multipath,
and a handshake wire-verified against Go and Rust stacks.
Proven on the wire, not just in unit tests
Section titled “Proven on the wire, not just in unit tests”quicz’s primary handshake and FIN-terminated stream-echo path are exercised by real UDP probes: loopback in-process, separate-process Zig, and certificate-verified clients written independently in Go and Rust.
$ zig-out/bin/quicz-tls13-process-echo-server 127.0.0.1 4443 2 concurrent-retry &$ (cd examples/interop/go_echo_client && \ go run . -addr 127.0.0.1:4443 -ca ../testdata/quicz-echo-ca.pem -server-name localhost)# quic-go client ↔ quicz server: TLS 1.3 handshake, then FIN-terminated# "hello" / "world" echoes verified on streams 0 and 4 — certificate# verification enabled the whole way.What quicz ships today
Section titled “What quicz ships today”- Pure-Zig TLS 1.3 + 0-RTT — no C crypto dependency; post-quantum X25519Kyber768.
- QUIC v1 and v2 transport — streams, flow control, connection migration, path validation, Retry, stateless reset, key update, version negotiation.
- DATAGRAM, multipath, ECN, PMTU, GSO/GRO, connection pooling, qlog.
- Loss recovery + NewReno / CUBIC / BBR with packet pacing.
- HTTP/3 + QPACK static and WebTransport at a basic level.
- Wire-verified interop with quic-go, quinn, and the QUIC-Interop-Runner.
var conn = try quicz.Connection.init( std.heap.page_allocator, .client, .{ .initial_max_data = 65_536, .initial_max_stream_data = 65_536, .initial_max_streams_bidi = 16,});defer conn.deinit();
const id = try conn.openStream();try conn.sendOnStream(id, "hello", true);
var buf: [1350]u8 = undefined;const frame = (try conn.pollTx(0, &buf)) orelse return error.NoPendingFrame;Full walkthrough in the quick start.
Interop matrix
Section titled “Interop matrix”| Peer | Language / stack | Probe |
|---|---|---|
| quic-go | Go | certificate-verified echo client/server |
| quinn | Rust | certificate-verified echo client |
| QUIC-Interop-Runner | — | handshake, transfer, retry self-test |
| quicz (separate processes) | Zig | independent client + server over loopback UDP |
Run it yourself: examples guide.
How quicz compares
Section titled “How quicz compares”The authoritative feature matrix tracks 37 capabilities across four stacks. Headline coverage:
| Metric | quic-go | quiche | s2n-quic | quicz |
|---|---|---|---|---|
| Transport (19 items) | 19/19 | 14/19 | 14/19 | 19/19 |
| Congestion (4 items) | 4/4 | 4/4 | 3/4 | 4/4 |
| Cipher suites (5 items) | 5/5 | 5/5 | 5/5 | 5/5 |
| Application layer (6 items) | 6/6 | 3/6 | 0/6 | 2/6 |
| Platform (3 items) | 2/3 | 0/3 | 1/3 | 1/3 |
| Total (37 items) | 36/37 | 26/37 | 23/37 | 31/37 |
quicz leads on transport, congestion, and cipher suites; the remaining gap is application-layer breadth. See the full feature-by-feature comparison for all 37 rows and the gap analysis.
What’s partial or not yet
Section titled “What’s partial or not yet”| Status | Capability |
|---|---|
| Basic, hardening in progress | HTTP/3 connection management (GOAWAY / SETTINGS / stream lifecycle); WebTransport sessions |
| Not yet | QPACK dynamic table; HTTP Datagrams (RFC 9297); stream reset partial delivery; FIPS 140-3; XDP zero-copy I/O |
The authoritative status and acceptance evidence live in the transport task matrix. The API is stabilizing but still evolving.
Where next?
Section titled “Where next?”- Quick start — add quicz to your Zig build and send your first frame.
- Feature comparison — quicz vs quic-go / quiche / s2n-quic, 37 rows.
- Architecture — how the endpoint, connection, and TLS layers fit together.
- Spec coverage — RFC 9000/9001/9002 section-by-section status.
- Examples — loopback, echo server, and Go/Rust interop commands.