Streaming AI Responses Intermediate
Streaming is what makes AI interfaces feel responsive. Instead of waiting seconds for a complete response, users see tokens appear in real time. This lesson covers the streaming protocols, how the AI SDK handles them, and how to build custom streaming logic.
How Streaming Works
AI providers stream responses using one of two protocols:
| Protocol | How It Works | Used By |
|---|---|---|
| Server-Sent Events (SSE) | Server pushes events over a long-lived HTTP connection | OpenAI, Anthropic, most providers |
| ReadableStream | Fetch API streams response body as chunks | Custom backends, edge functions |
Streaming with useChat (Recommended)
The useChat hook handles streaming automatically:
TypeScript
const { messages, input, handleInputChange, handleSubmit } = useChat({ api: '/api/chat', // The last message in the array updates in real-time as tokens arrive // No additional code needed for streaming! });
Custom Streaming with Fetch
For more control, you can implement streaming manually using the Fetch API:
TypeScript
async function streamAIResponse(prompt: string) { const response = await fetch('/api/chat', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ messages: [{ role: 'user', content: prompt }] }), }); const reader = response.body!.getReader(); const decoder = new TextDecoder(); let result = ''; while (true) { const { done, value } = await reader.read(); if (done) break; const chunk = decoder.decode(value, { stream: true }); result += chunk; setStreamedText(result); // Update React state } }
Streaming Performance Tips
Performance: When rendering streaming text, avoid re-rendering the entire message list on each token. Use
React.memo on message components and only update the currently streaming message. The useChat hook handles this automatically.
Handling Stream Interruption
Users should be able to stop a stream in progress:
TypeScript
const { messages, stop, isLoading } = useChat({ api: '/api/chat' }); // Show a stop button while streaming {isLoading && ( <button onClick={stop} className="stop-button"> Stop generating </button> )}
Streaming Mastered!
You understand how streaming works under the hood. In the next lesson, you will learn to manage AI state across conversations.
Next: State Management →
Lilly Tech Systems