Capítulo 107 de 116

Chapter 107: renderToReadableStream

Core Idea

renderToReadableStream(reactNode, options) is the Web Streams API equivalent of renderToPipeableStream (Ch 106) — same streaming-SSR-with-Suspense behavior, targeted at non-Node runtimes (edge functions, Deno, browsers' own streaming APIs) that speak the standard ReadableStream interface instead of Node's stream model.

Key Concepts

  • Returns a Promise resolving to a ReadableStream, rather than exposing a Node-style .pipe() method — fits directly into Response objects on edge/Web-standard server runtimes (e.g. new Response(stream)).
  • Same Suspense-driven streaming model as Ch 106: content outside Suspense boundaries streams first; content inside streams in as it resolves — the underlying streaming mechanics are shared between both render-to-stream APIs, only the target stream type differs.
  • onError/allReady: mirrors renderToPipeableStream's callback options conceptually — an allReady promise (awaited when a complete, non-streamed response is needed, e.g. for crawlers) alongside error-reporting hooks, adapted to the Promise-based Web API style rather than Node-style callbacks.
  • Runtime choice, not a behavior choice: pick this over renderToPipeableStream based on which streams API your deployment target actually supports — the streaming/Suspense semantics themselves are consistent between the two.

Code Examples

const stream = await renderToReadableStream(<App />, {
  bootstrapScripts: ['/main.js'],
});
return new Response(stream, { headers: { 'Content-Type': 'text/html' } });
  • What it demonstrates: producing a standard ReadableStream and handing it directly to a Web-standard Response object, the typical shape for an edge-runtime server handler.

Key Takeaways

  1. Choose this API specifically for Web Streams-based runtimes; choose renderToPipeableStream for Node.js — the streaming behavior itself is otherwise equivalent.
  2. It resolves a Promise for the stream rather than exposing an immediate .pipe() call, matching the async, Promise-oriented style of the Web Streams API.
  3. Suspense boundaries still fully control streaming granularity, exactly as in Ch 106.

Connects To

  • Ch 106 (renderToPipeableStream): the Node.js equivalent with the same underlying streaming/Suspense model.
  • Ch 70 (Suspense): the mechanism controlling what streams first.