Why Streaming Matters
Blank screen
All at once
Tool by tool
Event by event
When you call query(), you wait for the entire response before seeing anything. For short tasks, that is fine. But when an agent is reading files, running commands, and thinking for 30 seconds, your user stares at a blank screen. Streaming fixes that by sending you each piece of the response as it happens — word by word, tool by tool, event by event.
The Event Stream
When you use streaming mode, the SDK emits a sequence of events that tell you exactly what is happening inside your agent. Each event has a type and a payload:
Streaming in Practice
The SDK provides a streaming interface that lets you handle events as they arrive. Here is a complete example:
import { Claude } from "@anthropic-ai/claude-agent";
const agent = new Claude({
model: "claude-sonnet-4-6",
tools: "defaults",
});
// Use the streaming query method
const stream = agent.streamQuery(
"Read package.json and summarize the project."
);
// Listen for events as they arrive
for await (const event of stream) {
switch (event.type) {
case "text_delta":
// A chunk of text — print it immediately
process.stdout.write(event.text);
break;
case "tool_use":
// Claude is calling a tool
console.log(`\n[Tool: ${event.name}]`);
break;
case "tool_result":
// Tool finished — show a brief status
console.log(`[Tool complete]\n`);
break;
case "result":
// Final result with metadata
console.log(`\nCost: $${event.cost}`);
break;
}
}
Building a Real-Time Terminal UI
Here is a more polished example that shows tool activity and text output in a terminal interface — the kind of experience you see in Claude Code itself:
async function runWithUI(prompt: string) {
const agent = new Claude({
model: "claude-sonnet-4-6",
tools: "defaults",
});
console.log(`\x1b[36m> ${prompt}\x1b[0m\n`);
const stream = agent.streamQuery(prompt);
let toolDepth = 0;
for await (const event of stream) {
if (event.type === "tool_use") {
toolDepth++;
// Show tool activity in dim text
console.log(
`\x1b[2m ${" ".repeat(toolDepth)}[${event.name}]\x1b[0m`
);
} else if (event.type === "tool_result") {
toolDepth = Math.max(0, toolDepth - 1);
} else if (event.type === "text_delta") {
// Stream text in real time
process.stdout.write(event.text);
} else if (event.type === "result") {
console.log(`\n\x1b[2mCost: $${event.cost.toFixed(4)}\x1b[0m`);
}
}
}
runWithUI("Find all TypeScript files in this project and count the total lines of code.");
Event Lifecycle
Understanding the full event lifecycle helps you build robust UIs. Here is the sequence for a typical agent interaction:
User prompt: "How many .ts files are in src/?"
text_delta "Let me check"
text_delta " the src directory..."
tool_use Glob { pattern: "src/**/*.ts" }
tool_result ["src/index.ts", "src/utils.ts", ...]
text_delta "I found "
text_delta "12 TypeScript files"
text_delta " in the src/ directory."
result { cost: 0.003, toolCalls: 1 }
Notice how text deltas arrive in small chunks — sometimes just a word or part of a word. Tool events arrive as complete units. The result event always comes last and signals that the agent is done.
Common Pitfalls
If you only handle text_delta, you will miss tool activity and the final result. Always have a default case or handle at least text, tool_use, tool_result, and result events.
console.log() adds a newline after each call. Use process.stdout.write() for text deltas so words flow together naturally instead of appearing on separate lines.
Network issues, rate limits, or API errors can interrupt the stream. Wrap your for await loop in a try/catch to handle errors gracefully instead of crashing.
Streaming & Events
What is streaming in the Agent SDK?
text_delta event
tool_use event
tool_result event
result event
streamQuery() vs query()
Why use process.stdout.write() for text deltas?
Streaming & Events Check
1What is the main benefit of streaming over a regular query() call?
2Which event type represents a chunk of Claude text arriving in real time?
3A stream emits events in this order: text_delta, tool_use, tool_result, text_delta, result. What happened?
4Why should you NOT use console.log() for streaming text deltas?
5What should you do if the stream throws an error mid-execution?