Skip to main content
Stream API - Readable Streams

Stream API - Readable Streams

A ReadableStream is a source of chunks. You either pull chunks with a reader or push them through a pipe. Response bodies are the most common readable streams you will encounter.

Getting a reader

const response = await fetch('/api/events/live');
const reader = response.body.getReader();

try {
  while (true) {
    const { value, done } = await reader.read();
    if (done) break;
    handleChunk(value);
  }
} finally {
  reader.releaseLock();
}

Creating a readable stream

function counterStream(limit) {
  let current = 0;

  return new ReadableStream({
    pull(controller) {
      if (current >= limit) {
        controller.close();
        return;
      }

      controller.enqueue(current++);
    }
  });
}

for await (const value of counterStream(3)) {
  console.log(value); // 0, 1, 2
}

pull() is called whenever the consumer wants more data, which keeps production paced to consumption.

Pushing data with a controller

let controllerRef;

const stream = new ReadableStream({
  start(controller) {
    controllerRef = controller;
  }
});

function pushMessage(text) {
  controllerRef.enqueue(new TextEncoder().encode(text));
}

function finish() {
  controllerRef.close();
}

This pattern suits event sources such as chat messages or server-sent updates.

Cancellation

const stream = new ReadableStream({
  pull(controller) {
    // ...
  },
  cancel(reason) {
    console.log('Consumer cancelled:', reason);
    cleanup();
  }
});

Cancellation runs when the consumer aborts or stops reading. Use it to release sockets, timers, or file handles.

Teeing a stream

const response = await fetch('/api/large.csv');
const [forParsing, forBackup] = response.body.tee();

parseCsv(forParsing);
saveToDisk(forBackup);

tee() splits a stream into two independent branches. Both branches must be consumed, or backpressure from the slower one slows the source.

Async iteration

for await (const chunk of response.body) {
  view.append(chunk);
}

Async iteration is a concise alternative to a manual reader loop in browsers that support it.