Why Stream?
Streaming shows text as it is generated, so users see a fast, responsive UI instead of waiting.
By default, an API call waits until Claude has finished the whole reply, then returns it all at once. For a chatbot or a long answer, that means the user stares at a spinner.
Streaming fixes the wait
With streaming, Claude sends the reply piece by piece as it is generated. You render each piece immediately, so text appears to type itself onto the screen — just like the chat apps users expect.
When to stream
- Chat interfaces — responsiveness matters most.
- Long outputs — articles, code, reports.
- High max_tokens — streaming avoids request timeouts on big replies.
Example
// Without streaming: one long wait, then everything at once
const res = await client.messages.create({
model: "claude-opus-4-8", max_tokens: 2048,
messages: [{ role: "user", content: "Write a 500-word article about CSS grid." }],
});
// The user sees nothing until this whole call finishes.
// Streaming (next lesson) sends text as it is produced, so the UI feels instant.When to use it
- Display Claude's response word-by-word in a chat widget so users see activity immediately instead of a loading spinner.
- Stream a long code generation response so the user can start reading the function signature while the body is still being written.
- Show a live progress bar or typing indicator tied to incoming stream chunks to reduce perceived latency in a support bot.
More examples
Non-streaming vs. streaming comparison
Shows the default non-streaming call where nothing appears until the full response is ready.
// Non-streaming: wait for the full reply
const msg = await client.messages.create({
model: "claude-haiku-4-5",
max_tokens: 512,
messages: [{ role: "user", content: "Write a short story." }],
});
console.log(msg.content[0].text); // arrives all at onceEnable streaming with stream option
Switches to messages.stream and iterates the async generator to print each text delta immediately.
const stream = await client.messages.stream({
model: "claude-haiku-4-5",
max_tokens: 512,
messages: [{ role: "user", content: "Write a short story." }],
});
for await (const chunk of stream) {
if (chunk.type === "content_block_delta") {
process.stdout.write(chunk.delta.text); // prints each word as it arrives
}
}Measure time-to-first-token
Measures time-to-first-token to confirm streaming delivers early feedback much faster than a full response.
const start = Date.now();
const stream = await client.messages.stream({
model: "claude-haiku-4-5",
max_tokens: 256,
messages: [{ role: "user", content: "Tell me a fun fact." }],
});
let firstToken = true;
for await (const chunk of stream) {
if (firstToken && chunk.type === "content_block_delta") {
console.log(`First token in ${Date.now() - start} ms`);
firstToken = false;
}
}
Discussion