0PricingLogin
Next.js 15 Fullstack (App Router + Server Actions) · Lesson

Streaming Responses and ReadableStream in Handlers

Return incremental data with ReadableStream for AI tokens, logs, and progressive payloads.

Why Stream a Response?

A normal Route Handler builds the entire body in memory, then sends it all at once. For AI token output, live logs, or large reports, that means the user stares at a blank screen until the very end.

Streaming flips this: you push chunks to the client as they become available. The browser starts rendering the first bytes immediately, time-to-first-byte drops, and you never hold the whole payload in RAM.

  • ReadableStream is the Web Standard primitive Next.js 15 uses for this.
  • You return it directly from a Route Handler inside a Response.
  • It works on both the Node.js and Edge runtimes.

The ReadableStream Shape

A ReadableStream is constructed with an object containing a start(controller) method. Inside it you call controller.enqueue(chunk) to push data and controller.close() when finished.

The chunk should be a Uint8Array of bytes. A TextEncoder turns a string into those bytes. This is pure Web API code, so it runs anywhere a modern JS engine exists.

const encoder = new TextEncoder();

const stream = new ReadableStream({
  start(controller) {
    controller.enqueue(encoder.encode("Hello, "));
    controller.enqueue(encoder.encode("streamed "));
    controller.enqueue(encoder.encode("world!"));
    controller.close();
  },
});

const response = new Response(stream);
console.log("Stream and Response created:", response instanceof Response);

All lessons in this course

  1. Designing RESTful Route Handlers with the Web Request API
  2. Node Runtime vs Edge Runtime Tradeoffs
  3. Streaming Responses and ReadableStream in Handlers
  4. Request Validation and Typed JSON Responses with Zod
← Back to Next.js 15 Fullstack (App Router + Server Actions)