Claude API Streaming in Node.js / TypeScript

Stream Claude API responses in Node.js using @anthropic-ai/sdk. Print tokens as they arrive with the streaming helper or raw event stream.

💥 50p impulse-buy: Power Prompts PDF (first 10 buyers) 30 battle-tested Claude Code prompts · 8-page PDF · paste into CLAUDE.md and never re-type a prompt again · 50p impulse-buy, no commitment

The @anthropic-ai/sdk streaming helper handles SSE parsing automatically.

Simple streaming

import Anthropic from "@anthropic-ai/sdk";

const client = new Anthropic();

const stream = await client.messages.stream({
  model: "claude-sonnet-4-6",
  max_tokens: 1024,
  messages: [{ role: "user", content: "Write a function that parses CSV in JavaScript." }]
});

for await (const chunk of stream) {
  if (chunk.type === "content_block_delta" && chunk.delta.type === "text_delta") {
    process.stdout.write(chunk.delta.text);
  }
}
console.log();

Using the text stream helper

const stream = client.messages.stream({
  model: "claude-sonnet-4-6",
  max_tokens: 1024,
  messages: [{ role: "user", content: "Explain closures in JavaScript." }]
});

stream.on("text", (text) => process.stdout.write(text));
const finalMsg = await stream.finalMessage();
console.log(`
Used ${finalMsg.usage.output_tokens} output tokens.`);

Express.js streaming endpoint

import express from "express";
import Anthropic from "@anthropic-ai/sdk";

const app = express();
app.use(express.json());
const client = new Anthropic();

app.post("/stream", async (req, res) => {
  res.setHeader("Content-Type", "text/plain; charset=utf-8");
  res.setHeader("Transfer-Encoding", "chunked");

  const stream = await client.messages.stream({
    model: "claude-sonnet-4-6",
    max_tokens: 1024,
    messages: [{ role: "user", content: req.body.prompt }]
  });

  for await (const chunk of stream) {
    if (chunk.type === "content_block_delta" && chunk.delta.type === "text_delta") {
      res.write(chunk.delta.text);
    }
  }
  res.end();
});

app.listen(3000);

See the Python streaming example for server-side Python usage. For tool use with streaming, see the Node.js tool use example.

Frequently asked questions

How do I stream Claude in an Express.js endpoint?
Set `res.setHeader('Content-Type', 'text/plain; charset=utf-8')` and `res.setHeader('Transfer-Encoding', 'chunked')`, then `for await (const chunk of stream) { res.write(chunk.delta?.text ?? '') }`. Call `res.end()` after the loop.
Does streaming work with Vercel Edge Functions?
Yes. Use the `TransformStream` API and return a `Response` with a `ReadableStream`. The Anthropic SDK's async iterator is compatible with edge runtimes.
What events does the raw event stream emit?
The raw stream emits: `message_start`, `content_block_start`, `content_block_delta` (with text), `content_block_stop`, `message_delta` (with stop reason + usage), and `message_stop`. Most applications only need `content_block_delta`.

Free tools

Cost Calculator → API Cookbook → Diff Summarizer → Skills Browser →

More examples

Claude API Python QuickstartClaude API Node.js / TypeScript QuickstartClaude API Streaming in PythonClaude API Tool Use in PythonClaude API Tool Use in Node.js / TypeScriptClaude Prompt Caching in Python