Live AI Replies with Fetch and ReadableStream
§1 Fetch streaming turns waiting into live replies
A streaming chat interface starts showing an answer before the server finishes generating it. Instead of waiting for one complete response, the browser receives small pieces and adds them to the page. This makes long answers feel more responsive, even when the total generation time stays the same.
The main browser tools are fetch, which makes the request, and ReadableStream, which exposes the arriving response body. For AI products, these tools let you build the familiar experience of a reply appearing gradually.
§2 Response.body delivers bytes, not ready-made messages
A normal fetch workflow often ends with response.json() or response.text(). Those methods collect the entire response before returning the parsed result. For live output, check response.ok first, then read response.body instead.
The body is a ReadableStream. Calling its getReader() method gives you a reader, and repeatedly calling reader.read() returns arriving chunks. Each result contains a value and a done flag. When done becomes true, the body has ended.
A network chunk is not necessarily one AI token or one event. A chunk might contain several messages, half a message, or part of a character. Your browser code must handle those boundaries rather than assuming each read produces displayable text.
§3 TextDecoder and an event buffer reconstruct the reply
The chunks returned by the reader are byte arrays. A TextDecoder converts them into text. Use its streaming option while decoding successive chunks so characters split between chunks are preserved. Flush the decoder when the stream ends to process any remaining bytes.
Many AI endpoints use Server-Sent Events, or SSE, as their response format. SSE carries text events separated by blank lines, often with payloads on data: lines. Although EventSource is the browser’s dedicated SSE interface, fetch is useful when you need a POST body or custom request headers.
Keep an unfinished-text buffer between reads. Append decoded text, extract complete events, and retain the incomplete remainder for the next read. A reliable parser handles line endings and multiple data lines. Prefer a maintained SSE parser over splitting every chunk independently.
After parsing an event, interpret its payload according to your API’s documentation. For an OpenAI-style chat stream, this commonly means reading incremental content from a JSON delta. A completion marker such as [DONE] is a protocol convention, not a feature of ReadableStream itself.
§4 A backend keeps API credentials out of the browser
The simplest safe architecture is browser, your backend, then your AI provider. The browser sends the conversation to your backend. Your backend attaches the private API credential, requests a streaming response, and forwards the stream without collecting the full answer first.
Fluxio fits this setup as a streaming-first, pay-per-token AI API relay. One key provides access to multiple model families, including options such as Claude Sonnet 5 and Gemini 2.5 Flash. For OpenAI-style clients, its API base is https://api.fluxioapi.com/v1. Keep that credential on your server, not in frontend JavaScript.
Your hosting stack also matters. Reverse proxies, compression layers, and server frameworks can buffer output. Verify that small pieces reach the deployed browser promptly; working locally does not guarantee live delivery in production.
§5 Rendering, cancellation, and errors complete the experience
- – Append answer text through textContent or your framework’s escaped text rendering, rather than treating generated output as trusted HTML.
- – Batch rapid updates to avoid repainting the page for every tiny fragment, especially during long replies.
- – Connect a Stop button to an AbortController passed into fetch, and have your backend propagate cancellation upstream where supported.
- – Handle non-success HTTP responses before reading, and handle network failures or provider error events during the stream.
- – Preserve partial replies after an interruption and label them clearly rather than presenting an unfinished answer as complete.
Test with slow connections, split events, and cancelled requests. A dependable streaming interface is not just fast text: it makes progress visible and makes interruptions understandable.
Sign up for Fluxio to build your first live AI reply.