Summary
Support streaming SSR output for request-time routes. All mature frameworks (Astro, SvelteKit, Next.js, Remix) support streaming; openElement currently buffers the entire DSD render before sending.
Competitive context
| Framework |
Streaming SSR |
| Astro |
Built-in (5.x), opt-out available |
| SvelteKit |
Built-in via transformPageChunk |
| Next.js |
Built-in (RSC streaming) |
| Remix |
Built-in (<Meta>, <Links> stream first) |
| Fresh |
Not supported |
| openElement |
Not supported — buffered render |
Technical feasibility
openElement's DSD model is naturally stream-compatible:
<template shadowrootmode="open"> can be emitted as soon as the component renders
- The HTML document shell (
<head>, app shell) can stream first
- Individual route components render independently
The renderDsdTree() async path already yields per-component; the gap is in the HTTP response layer (Hono/Nitro) which currently awaits the full string.
Proposed design
renderRoute returns a ReadableStream instead of string for request-time routes
- Document shell streams immediately (head + app shell opening tags)
- Route DSD content streams as rendered
- Closing tags + client scripts stream last
- SSG remains buffered (static files don't benefit from streaming)
Non-goals
- No React Suspense-style selective hydration boundaries
- No streaming for SSG output (static files)
- No partial DSD (entire component shadow root streams as one chunk)
Target version
0.43.0 or 0.44.0 (candidate for both; depends on 0.43 WC SSR scope)
Summary
Support streaming SSR output for request-time routes. All mature frameworks (Astro, SvelteKit, Next.js, Remix) support streaming; openElement currently buffers the entire DSD render before sending.
Competitive context
transformPageChunk<Meta>,<Links>stream first)Technical feasibility
openElement's DSD model is naturally stream-compatible:
<template shadowrootmode="open">can be emitted as soon as the component renders<head>, app shell) can stream firstThe
renderDsdTree()async path already yields per-component; the gap is in the HTTP response layer (Hono/Nitro) which currently awaits the full string.Proposed design
renderRoutereturns aReadableStreaminstead ofstringfor request-time routesNon-goals
Target version
0.43.0 or 0.44.0 (candidate for both; depends on 0.43 WC SSR scope)