Why Streaming?
Traditional SSR waits for the entire page to render before sending any content:- Faster First Contentful Paint (FCP)
- Better Time to Interactive (TTI)
- Improved perceived performance
- Better user experience on slow connections
Enabling Streaming
Use thedefaultStreamHandler instead of defaultRenderHandler:
app/server.ts
How Streaming Works
TanStack Start uses React’s streaming SSR capabilities:1. Initial HTML Shell
The server immediately sends the HTML shell:2. Component Streaming
As components render, their HTML streams to the browser:3. Suspense Boundaries
React Suspense enables selective streaming:- Server sends
<h1>Dashboard</h1>immediately - Server sends both
<div>Loading stats...</div>and<div>Loading activity...</div> - When
Statsdata loads, server sends<Stats />HTML and inline script to replace fallback - When
Activitydata loads, server sends<Activity />HTML and inline script to replace fallback
4. Hydration After Streaming
After HTML arrives, React hydrates the page:app/client.tsx
- Reads serialized state from the HTML
- Attaches event listeners
- Makes the page fully interactive
Streaming Server Functions
Server functions can also stream responses:Async Generators
Use generator functions to stream data:ReadableStream
Return aReadableStream for binary data streaming:
Frame Protocol
For advanced streaming scenarios, TanStack Start uses a binary frame protocol to multiplex JSON and raw streams:Protocol Format
Each frame has a header:0- JSON data (streamId 0)1- Raw stream chunk (streamId > 0)2- Stream end (streamId > 0)3- Stream error (streamId > 0)
Internal Implementation
The frame protocol is used internally when server functions return both serialized data and raw streams:Streaming Patterns
Progressive Data Loading
Load and display data progressively:Parallel Data Fetching
Load independent sections in parallel:Nested Suspense
Create sophisticated loading experiences:Performance Optimization
Chunk Size
Control streaming chunk size for optimal performance:Selective Streaming
Don’t stream everything - use Suspense strategically:Preloading Critical Data
Load critical data in route loaders:Debugging Streaming
Streaming can be harder to debug. Use these techniques:Log Stream Events
Network Inspection
In browser DevTools:- Open Network tab
- Click on the streaming request
- Watch the Response tab update in real-time
Disable Streaming Temporarily
Switch to string rendering to debug:Best Practices
Use streaming by default
Use streaming by default
Streaming improves perceived performance for most applications:
Add Suspense boundaries strategically
Add Suspense boundaries strategically
Wrap slow-loading content, not everything:
Provide meaningful loading states
Provide meaningful loading states
Show skeletons that match final content:
Test on slow connections
Test on slow connections
Use browser DevTools to throttle network speed and test streaming behavior.
Monitor streaming metrics
Monitor streaming metrics
Track First Contentful Paint (FCP) and Time to Interactive (TTI) to measure streaming impact.
Related Concepts
Server Rendering
Learn how SSR enables streaming
Server Functions
Stream data from server functions
SSR & Streaming Guide
Complete guide to SSR and streaming
Deployment
Deploy streaming applications