# 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.

URL: https://webtransport.day/guides/test-webtransport-locally/
Updated: 2026-10-28
Facts checked: 2026-10-28

**Short answer:** To test WebTransport locally, run a library's example server, open the browser client it serves, and connect with the server's self-signed certificate hash through serverCertificateHashes. The Rust wtransport "full" example and the Go webtransport-go example both do this. Neither needs browser flags. Commands below follow each project's README.

## Key facts

- **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.


## Option 1: Rust, the wtransport "full" example

The [wtransport](https://github.com/BiagioFesta/wtransport) repository includes `client.rs`, `server.rs`, `full.rs` and `gencert.rs` in its examples. From a clone of the repository:

```sh
cargo run --example full
```

According to the example's source, it:

- starts an HTTP server on `127.0.0.1:8080` serving a test page, and a WebTransport server on an operating-system-assigned UDP port,
- creates a self-signed identity for `localhost`, `127.0.0.1` and `::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](https://github.com/quic-go/webtransport-go) README says it implements draft-16, and its `example` directory has a server, a Go client and a browser client:

```sh
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](https://github.com/w3c/webtransport/tree/main/samples/echo)), or the Python `aioquic` examples, where `demo.py` echoes datagrams and stream data at `/wt`. The aioquic examples README gives the server command:

```sh
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](/guides/debug-webtransport-handshake-errors/):

```sh
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](/tools/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):

```js
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](/guides/debug-webtransport-handshake-errors/). For library choices, see [WebTransport libraries](/guides/webtransport-client-libraries/).

## FAQ

### 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

- [BiagioFesta/wtransport: examples (client, server, full, gencert)](https://github.com/BiagioFesta/wtransport)
- [wtransport full example source](https://github.com/BiagioFesta/wtransport/blob/master/wtransport/examples/full.rs)
- [quic-go/webtransport-go: example README](https://github.com/quic-go/webtransport-go/tree/master/example)
- [aioquic examples README](https://github.com/aiortc/aioquic/blob/main/examples/README.rst)
- [W3C WebTransport samples: echo](https://github.com/w3c/webtransport/tree/main/samples/echo)
- [MDN: WebTransport() constructor (serverCertificateHashes)](https://developer.mozilla.org/en-US/docs/Web/API/WebTransport/WebTransport)
