Most frontend developers know exactly one networking API: fetch(). But the browser's networking toolkit goes much deeper — streaming responses, resumable background downloads, dictionary-compressed payloads, and even raw QUIC connections. This guide tours the full stack, with the honest limits of each API spelled out.
fetch() doesn't have to be all-or-nothing. The response body is a ReadableStream — you can process data as it arrives, which is how you build progress bars, live logs, and chat-style token streaming:
Need to transform a stream mid-flight — say, decrypting or decompressing chunks? Pipe it through a TransformStream:
Regular fetch() dies with your tab. The Background Fetch API hands large downloads (podcasts, datasets, asset packs) to the browser itself, which keeps downloading even if the user navigates away — and shows native progress UI:
Honest limits: it requires a registered service worker, it's Chromium-only for now, and it's designed for downloads (uploads aren't supported). For everyday small requests, plain fetch() is still the right tool.
If your app downloads many similar files — versions of a WASM module, map tiles, ML weights — most bytes repeat. Compression Dictionary Transport (rolling out in Chromium) lets the browser reuse a previously-downloaded file as a Brotli/Zstandard dictionary, so each subsequent download only transfers the diff:
This is an emerging standard — check current browser support before depending on it — but the direction is clear: the browser is becoming a smarter, delta-aware download manager.
When to use what: small JSON → plain fetch(). Progressive rendering → streams. Multi-hundred-MB downloads the user might background → Background Fetch. Near-identical repeated payloads → compression dictionaries.
WebSockets run over TCP, so one dropped packet stalls every stream on the connection (head-of-line blocking). WebTransport runs over HTTP/3's QUIC, giving you independent, multiplexed streams where a lost packet only delays its own stream:
The honest part: WebTransport needs a server that speaks HTTP/3 — you can't use it against a plain HTTPS endpoint, and there's no "WebTransport echo server" built into browsers for testing. It's the right tool for game networking, live media, and low-latency sync when you control the server. For everything else, WebSockets remain the pragmatic default.
Prototyping against an API that doesn't exist yet (or is blocked by CORS)? A service worker can intercept fetch and return synthetic responses — no backend, no proxy, fully offline:
This is genuinely useful inside a client-side IDE: build the whole frontend against mocked endpoints, then swap in the real API later without changing a line of UI code.
Streams, mocks, and offline patterns — test them all in a zero-setup browser IDE.
Launch NitroIDE