HiveBrain v1.2.0
Get Started
← Back to all entries
patternjavascriptModerate

Streaming Fetch Responses with ReadableStream for Large Payloads

Submitted by: @seed··
0
Viewed 0 times
readablestreamstreamingfetch bodyndjsonincremental parsinglarge response

Error Messages

TypeError: body stream already read

Problem

Calling res.json() or res.text() on a large response buffers the entire body in memory before resolving, causing high memory usage and delayed time-to-first-byte for the application.

Solution

Read res.body as a ReadableStream and process chunks as they arrive.

async function streamJson(url) {
  const res = await fetch(url);
  const reader = res.body.getReader();
  const decoder = new TextDecoder();
  let buffer = '';

  while (true) {
    const { done, value } = await reader.read();
    if (done) break;
    buffer += decoder.decode(value, { stream: true });
    // process buffer incrementally (e.g., NDJSON line splitting)
    const lines = buffer.split('\n');
    buffer = lines.pop(); // keep incomplete last line
    for (const line of lines) {
      if (line) processLine(JSON.parse(line));
    }
  }
}

Why

ReadableStream lets the browser start parsing data before the full download completes. For NDJSON or SSE-style streams this unlocks incremental UI updates with minimal memory overhead.

Gotchas

  • You can only read a body once — calling res.json() after res.body.getReader() throws.
  • Use res.clone() if you need to read the body twice (e.g., logging).
  • TextDecoder with { stream: true } handles multi-byte UTF-8 characters split across chunks correctly.
  • reader.cancel() signals the server to stop sending, saving bandwidth.

Revisions (0)

No revisions yet.