How to test WebTransport locally with an example server
Run a local WebTransport server from the wtransport or webtransport-go examples, then connect from the browser, with a self-signed certificate hash.
WebTransport Day
Published
Last updated:
Facts checked:
2 min read
- Updated Oct 28, 2026
- ✓ Facts checked Oct 28, 2026
- Sources: MDN
Key facts (checked October 28, 2026)
- Rust example
- cargo run --example full (acknowledges with ACK, does not echo)
- Go example
- go run . in example/server (README does not say whether it echoes)
- Certificate
- ECDSA P-256, validity under two weeks, for serverCertificateHashes
What do I need to test WebTransport locally?
You need three things: a server that speaks WebTransport over HTTP/3, a certificate the browser will accept, and a client. The easiest path is to let a library’s example generate a self-signed certificate and serve its own test page. The commands below come from each project’s README and example source as of 2026-10-28. Treat them as examples and check the repository for current instructions.
Text version
- The browser sends "hello" to the server on a stream (blue) or as a datagram (amber).
- The echo server sends the same bytes back (teal-green).
- The browser shows the echo. If it arrives, DNS, UDP, QUIC, HTTP/3, the certificate and the origin check all worked.
Option 1: Rust, the wtransport “full” example
The wtransport repository includes client.rs, server.rs, full.rs and gencert.rs in its examples. From a clone of the repository:
cargo run --example full
According to the example’s source, it:
- starts an HTTP server on
127.0.0.1:8080serving a test page, and a WebTransport server on an operating-system-assigned UDP port, - creates a self-signed identity for
localhost,127.0.0.1and::1, and - injects the SHA-256 hash of that certificate into the page, which passes it as
serverCertificateHashes.
Open http://127.0.0.1:8080, press connect, and send something. The server acknowledges each stream and datagram with the text ACK; it does not echo your bytes back.
Option 2: Go, the webtransport-go example
The webtransport-go README says it implements draft-16, and its example directory has a server, a Go client and a browser client:
cd example/server
go run .
Per the example README, the server prints the certificate hash, serves a browser client at http://localhost:6120, and runs WebTransport at https://localhost:6121/webtransport. The certificate is a deterministically generated P-256 certificate that rotates weekly. Open the browser client with the hash pre-filled and press connect. The README does not say whether this server echoes data, so check its source if you need that.
Option 3: a true echo server
For a server that returns your bytes, use the W3C WebTransport samples echo server (source), or the Python aioquic examples, where demo.py echoes datagrams and stream data at /wt. The aioquic examples README gives the server command:
python examples/http3_server.py --certificate cert.pem --private-key key.pem
Their echo endpoint is then https://localhost:4433/wt. That README accepts an older draft than current browsers may expect and mentions Chrome flags for self-signed certificates; we could not confirm interoperability with current browsers, so verify before relying on it.
How do I use my own certificate?
Generate an ECDSA P-256 certificate valid for less than two weeks and hash it, as described in debugging handshake errors:
openssl req -x509 -newkey ec -pkeyopt ec_paramgen_curve:prime256v1 -nodes \
-days 13 -subj "/CN=localhost" -addext "subjectAltName=DNS:localhost" \
-keyout key.pem -out cert.pem
openssl x509 -in cert.pem -outform der | openssl dgst -sha256
Start your server with cert.pem and key.pem, then paste the hash into the self-signed certificate field in the WebTransport tester and connect to https://localhost:<port>/<path>.
How do I test my own client code?
Use the example server for the transport and write your client against it. A minimal browser client looks like this (an example, with a placeholder URL and hash handling left to you):
const hash = Uint8Array.from(/* 32 bytes of your certificate's SHA-256 */);
const transport = new WebTransport('https://localhost:4433/echo', {
serverCertificateHashes: [{ algorithm: 'sha-256', value: hash }],
});
await transport.ready;
console.log('connected');
transport.close();
If the connection fails, work through the handshake checklist. For library choices, see WebTransport libraries.
Frequently asked questions
Why does the Rust example reply "ACK" instead of echoing my text?
Its source acknowledges bidirectional streams and datagrams with the literal text ACK. It confirms that the whole path works but does not return your bytes. For a true echo, use the W3C samples echo server or the aioquic demo.
Do I need Chrome flags to connect to localhost?
Not with serverCertificateHashes: the example pages pass the hash, which tells the browser to trust that self-signed certificate. Older aioquic instructions mention flags such as --ignore-certificate-errors-spki-list; we could not confirm they are still required.
Can I connect to my local server from the hosted tester?
The hosted tester can connect to an https URL such as https://localhost:4433/ if your server allows this site's origin and you supply the certificate hash. Many example servers do not restrict origins, but check yours.
Sources
Facts on this page were last checked against these sources on October 28, 2026.
Cite this page
- Title
- How to test WebTransport locally with an example server
- Author
- WebTransport Day (organization)
- URL
- https://webtransport.day/guides/test-webtransport-locally/
- Updated
WebTransport Day. "How to test WebTransport locally with an example server." Last updated October 28, 2026. https://webtransport.day/guides/test-webtransport-locally/
Related reading
Debugging WebTransport handshake errors: a practical checklist
Why a WebTransport connection fails and what to check: certificates, serverCertificateHashes, HTTP/3 support, UDP, origin and path, per the spec.
Updated
WebTransport client and server libraries: what exists and its status
Verified WebTransport libraries for Rust, Go, Python, Node.js, .NET and Deno, with licence, latest release and the status caveats each project states.
Updated
What is WebTransport? Streams, datagrams, HTTP/3 and QUIC explained
WebTransport explained: one multiplexed HTTP/3 connection with reliable streams and unreliable datagrams. How it works, support and standards status.
Updated