Streaming and Deferred Boundaries
Stream a response so slow data arrives after the shell, without blocking the rest of the page.
Example
Keep the route tree shared and change the delivery adapter—not the component contract—when moving between client, server, and static rendering.
import { createSPA, hydrateSPA } from '@askrjs/askr/boot';
const root = document.getElementById('app')!;
if (root.childNodes.length) {
await hydrateSPA({ root, registry });
} else {
await createSPA({ root, registry });
}Streaming lifecycle
renderToStream from @askrjs/askr/ssr takes the same render options as renderToString plus two callbacks: onChunk(html), called as HTML fragments become ready, and onComplete(), called once the stream is finished. renderRouteRequest can also produce a stream: ReadableStream<Uint8Array> on its result when the route is rendered this way, so a single request-handling call site can support both buffered and streamed output.
Deferred boundaries
Each in-flight async boundary during a render is tracked as a DeferredBoundaryRegistration on the active RenderContext, with an id, a promise, and fulfilled(value)/rejected(error) callbacks that produce the replacement markup once the promise settles. The render context accumulates these in deferredBoundaries, which is how streaming SSR knows what's still pending after the initial shell has been flushed.
Failure handling
A deferred boundary's rejected(error) callback returns the fallback markup for that slot rather than throwing and killing the whole stream — one slow or failing data dependency doesn't take down the rest of the page. Because each boundary resolves independently, a client waiting on a chunk that errors still receives the other chunks in order.
Proxy buffering
Streaming SSR only delivers its latency benefit if nothing between your server and the browser buffers the whole response before forwarding it. Reverse proxies, CDNs, and some hosting platforms buffer by default, which silently turns a streamed response back into a blocking one — check your proxy's streaming/chunked-transfer configuration if renderToStream isn't producing progressive output at the client.