WebTransport Echo

Overview

This site helps people working with the WebTransport standard understand the current lay of the land, and the practical issues that emerge while building on it. Use the echo below to test what your browser is capable of. For the subtleties involved, see the Compatibility tab.

Example code

Connecting to this echo from a browser, Node, Go or Rust
const wt = new WebTransport('https://echo.semantic-ui.com/echo');
await wt.ready;

const writer = wt.datagrams.writable.getWriter();
await writer.write(new TextEncoder().encode('hello'));

const reader = wt.datagrams.readable.getReader();
const { value } = await reader.read();  // "hello"

The specification replaced datagrams.writable with createWritable() in 2025. Safari ships the current shape and Chrome still ships the old attribute, so feature-detect the writer. readable is an accessor on every engine.

import { WebTransport } from '@fails-components/webtransport';

const wt = new WebTransport('https://echo.semantic-ui.com/echo');
await wt.ready;

const writer = wt.datagrams.writable.getWriter();
await writer.write(new TextEncoder().encode('hello'));

Nothing in Node terminates or dials WebTransport without a native addon. This package is the one with production use behind it.

var transport webtransport.Transport

_, session, err := transport.Dial(context.Background(), "https://echo.semantic-ui.com/echo", nil)
if err != nil {
    log.Fatal(err)
}

session.SendDatagram([]byte("hello"))
echo, _ := session.ReceiveDatagram(context.Background())
fmt.Println(string(echo)) // hello

The Go client requires the peer to negotiate RESET_STREAM_AT, which no browser does. It reaches the Go endpoints here but not :4438.

let config = ClientConfig::default();

let connection = Endpoint::client(config)?
    .connect("https://echo.semantic-ui.com/echo")
    .await?;

connection.send_datagram(b"hello")?;
let echo = connection.receive_datagram().await?;

Connect

idle
Certificate hash and protocols

Echo is budgeted: 1 MiB and 120 seconds per session, four sessions per address. Far above any interop or development test.

Server Diagnostics

The most common frustration when building with WebTransport is that the client gives you nowhere near enough information to determine why a handshake failed. Below is what this server recorded for your attempt above, which carries considerably more than the browser will ever hand you.

Connect above, then this fills in with what arrived here from your address.

Additional Diagnostic Endpoints

These test slight variations in the handshake, which can produce different results depending on the browser. Use them to find which part your own disagrees with. All of them run the same echo handler behind the same certificate.