TypeScript/JavaScript SDK Basics
11 examples to get you started with the TypeScript/JavaScript SDK, 7 basic and 4 intermediate.
Search across all documentation pages
11 examples to get you started with the TypeScript/JavaScript SDK, 7 basic and 4 intermediate.
npm install @anthropic-ai/sdk.ANTHROPIC_API_KEY environment variable.Add the official SDK to your project with your package manager of choice.
npm install @anthropic-ai/sdk@types package is needed.Store your API key outside your source code and let the client pick it up automatically.
# .env.local (never commit this file)
ANTHROPIC_API_KEY=sk-ant-...process.env.ANTHROPIC_API_KEY by default, so you rarely need to pass a key explicitly in code..env file.Create an Anthropic client instance once and reuse it across requests.
import Anthropic from "@anthropic-ai/sdk";
const client = new Anthropic();
// Reads ANTHROPIC_API_KEY from process.env automaticallynew Anthropic() with no arguments picks up ANTHROPIC_API_KEY from the environment.new Anthropic({ apiKey: "..." }) if you're loading it from a custom secrets source.Related: The Anthropic TypeScript SDK Mental Model - how the client and its fetch-based transport fit together
Call client.messages.create() to get a single, non-streamed response from Claude.
import Anthropic from "@anthropic-ai/sdk";
const client = new Anthropic();
const message = await client.messages.create({
model: "claude-sonnet-5",
max_tokens: 1024,
messages: [{ role: "user", content: "Explain what a closure is in one sentence." }],
});
console.log(message.content);model, max_tokens, and messages are the required fields for a messages.create() call.claude-sonnet-5 is the default model in the current Claude lineup and a good starting point for most tasks..then()).message.content is an array of content blocks, not a plain string, since a response can mix text, tool calls, and other block types.Related: TypeScript SDK Type Reference for Content Blocks - what's actually inside that content array
Narrow the response's content blocks using the SDK's discriminated union types.
import Anthropic from "@anthropic-ai/sdk";
const client = new Anthropic();
const message = await client.messages.create({
model: "claude-sonnet-5",
max_tokens: 1024,
messages: [{ role: "user", content: "Say hello in three languages." }],
});
for (const block of message.content) {
if (block.type === "text") {
console.log(block.text);
}
}type discriminant ("text", "tool_use", "thinking", and so on), which TypeScript uses to narrow the type.block.type === "text" before reading block.text gives you compile-time safety instead of an any-typed guess.usage, stop_reason, and role, all fully typed.block.type === "tool_use" instead.Build up the messages array across turns to give Claude conversation history.
import Anthropic from "@anthropic-ai/sdk";
const client = new Anthropic();
const history: Anthropic.MessageParam[] = [
{ role: "user", content: "What's the capital of France?" },
{ role: "assistant", content: "The capital of France is Paris." },
{ role: "user", content: "What's its population?" },
];
const reply = await client.messages.create({
model: "claude-sonnet-5",
max_tokens: 512,
messages: history,
});Anthropic.MessageParam is the exported type for a single message entry, useful for typing arrays you build up over time.messages on every call."user" and "assistant", and the array should generally start with a "user" message.history before the next call to keep the conversation growing correctly.Steer Claude's behavior with a system prompt, separate from the conversation itself.
import Anthropic from "@anthropic-ai/sdk";
const client = new Anthropic();
const message = await client.messages.create({
model: "claude-sonnet-5",
max_tokens: 256,
system: "You are a terse assistant. Answer in a single sentence.",
messages: [{ role: "user", content: "Why is the sky blue?" }],
});system is a top-level parameter, not a message with role "system", and applies to the whole request.max_tokens caps the length of Claude's reply and counts against your usage, so set it to what the task actually needs.max_tokens too aggressively can cut a response off mid-thought; check stop_reason on the response if replies look truncated.claude-sonnet-5 for claude-haiku-4-5 on latency-sensitive paths or claude-opus-4-8 for the hardest reasoning tasks.Consume tokens as they arrive instead of waiting for the full response.
import Anthropic from "@anthropic-ai/sdk";
const client = new Anthropic();
const stream = client.messages.stream({
model: "claude-sonnet-5",
max_tokens: 1024,
messages: [{ role: "user", content: "Write a haiku about databases." }],
});
for await (const event of stream) {
if (event.type === "content_block_delta" && event.delta.type === "text_delta") {
process.stdout.write(event.delta.text);
}
}client.messages.stream() returns an async iterable, so for await consumes events without manual event-listener wiring.event.type, mirroring the pattern used for content blocks..finalMessage() if you want the assembled result after the loop ends.messages.create() when you only need the final text.Related: Async Iterators for Streaming in the TypeScript SDK - a deeper look at consuming stream events
Handle API failures with the SDK's specific error classes instead of a generic catch-all.
import Anthropic from "@anthropic-ai/sdk";
const client = new Anthropic();
try {
await client.messages.create({
model: "claude-sonnet-5",
max_tokens: 1024,
messages: [{ role: "user", content: "Hello" }],
});
} catch (error) {
if (error instanceof Anthropic.RateLimitError) {
console.warn("Rate limited, back off and retry.");
} else if (error instanceof Anthropic.APIConnectionError) {
console.error("Network issue reaching the API.");
} else {
throw error;
}
}RateLimitError, BadRequestError, and APIConnectionError let you branch on instanceof with full type narrowing.status code and response details, useful for logging or surfacing a specific message to users.else branch) avoids silently swallowing bugs you didn't anticipate.Related: TypeScript SDK Error Class Reference - the full list of error classes and when each one fires
Tune resilience settings and cancel in-flight requests with AbortController.
import Anthropic from "@anthropic-ai/sdk";
const client = new Anthropic({
maxRetries: 3,
timeout: 20_000,
});
const controller = new AbortController();
setTimeout(() => controller.abort(), 5_000);
const message = await client.messages.create(
{
model: "claude-sonnet-5",
max_tokens: 1024,
messages: [{ role: "user", content: "Summarize this in one line." }],
},
{ signal: controller.signal }
);maxRetries and timeout are client-level defaults; both can also be overridden per request.AbortController's signal as a request option lets you cancel a call from user interaction (like a "Stop generating" button).AbortController API.Related: Retry, Timeout, and AbortController Patterns in the TypeScript SDK - backoff tuning and cancellation in more depth
Use the identical client code in a Vercel Edge Function, Cloudflare Worker, or Node server.
export const runtime = "edge";
import Anthropic from "@anthropic-ai/sdk";
const client = new Anthropic();
export async function POST(request: Request) {
const { prompt } = await request.json();
const message = await client.messages.create({
model: "claude-sonnet-5",
max_tokens: 512,
messages: [{ role: "user", content: prompt }],
});
return Response.json(message);
}fetch, this route handler needs no Node-specific APIs and runs unchanged under export const runtime = "edge".new Anthropic() call works whether the code executes in Node.js, Vercel Edge, Cloudflare Workers, or Deno Deploy.max_tokens and any streaming loop mindful of that.ANTHROPIC_API_KEY still need to be configured for the edge environment specifically, since it's a separate runtime from your Node deployment.Related: Running the Anthropic SDK on Edge Runtimes - edge-specific configuration and gotchas | Strongly Typed Tool Definitions with Zod in TypeScript - typing tool calls once you go beyond plain text messages
Stack versions: Written against the Claude model lineup current as of ~June 2026 - Claude Fable 5, Claude Opus 4.8, Claude Sonnet 5 (the default), and Claude Haiku 4.5 - and the official
@anthropic-ai/sdkTypeScript SDK (latest release). Model names, SDK versions, and pricing move quickly - verify current specifics at platform.claude.com/docs before relying on them.
Reviewed by Chris St. John·Last updated Jul 19, 2026