import Anthropic from "@anthropic-ai/sdk";const client = new Anthropic({ apiKey: process.env.ANTHROPIC_API_KEY });const message = await client.messages.create({ model: "claude-sonnet-4-6", max_tokens: 1024, messages: [{ role: "user", content: "Explain async/await in JavaScript." }],});console.log(message.content[0].text);
Streaming response
JAVASCRIPT
const stream = await client.messages.create({ model: "claude-sonnet-4-6", max_tokens: 1024, stream: true, messages: [{ role: "user", content: "Write a short story." }],});for await (const event of stream) { if (event.type === "content_block_delta") { process.stdout.write(event.delta.text); }}
System prompt + multi-turn conversation
JAVASCRIPT
const response = await client.messages.create({ model: "claude-sonnet-4-6", max_tokens: 2048, system: "You are a senior backend engineer. Be concise and precise.", messages: [ { role: "user", content: "What's wrong with N+1 queries?" }, { role: "assistant", content: "N+1 queries happen when..." }, { role: "user", content: "How do I fix it in PostgreSQL?" }, ],});
Tool use (function calling)
JAVASCRIPT
const response = await client.messages.create({ model: "claude-sonnet-4-6", max_tokens: 1024, tools: [ { name: "get_weather", description: "Get current weather for a city", input_schema: { type: "object", properties: { city: { type: "string", description: "City name" }, }, required: ["city"], }, }, ], messages: [{ role: "user", content: "What's the weather in Tokyo?" }],});// Check if Claude wants to use a toolif (response.stop_reason === "tool_use") { const toolUse = response.content.find((b) => b.type === "tool_use"); console.log(toolUse.name, toolUse.input); // get_weather { city: 'Tokyo' }}
Prompt caching — reduce costs on large system prompts
JAVASCRIPT
const response = await client.messages.create({ model: "claude-sonnet-4-6", max_tokens: 1024, system: [ { type: "text", text: "You are an expert codebase assistant...\n\n[large context here]", cache_control: { type: "ephemeral" }, // cache this block }, ], messages: [{ role: "user", content: "Explain the auth module." }],});// Subsequent calls with same system block → cache hit → ~90% cheaper
Claude Code — useful workflows
BASH
# One-shot: explain code without starting REPLclaude -p "Explain what this does" < src/utils/parser.ts# Pipe output from another commandgit diff | claude -p "Summarize what changed in plain English"# Use in scriptsSUMMARY=$(claude -p "Summarize this log" < app.log)echo "$SUMMARY"# Ask Claude to write testsclaude "Write unit tests for src/auth/login.ts using Vitest"# Ask Claude to fix a failing testclaude "The test in auth.test.ts is failing — fix it"# Review a PRclaude /review-pr 42
CLAUDE.md — project instructions
Create CLAUDE.md in your repo root. Claude Code reads it on every session:
MARKDOWN
# Project: My App## Stack- Node.js 20, TypeScript, Fastify, PostgreSQL- Tests: Vitest, run with `pnpm test`- Lint: `pnpm lint` (ESLint + Prettier)## Conventions- Use named exports, no default exports- Prefer `async/await` over `.then()`- All DB queries go in `src/db/queries/`## Commands- `pnpm dev` — start dev server- `pnpm build` — production build- `pnpm test` — run tests
Batch API — process many prompts at once
JAVASCRIPT
// Create a batch (async, ~1hr processing)const batch = await client.messages.batches.create({ requests: [ { custom_id: "req-1", params: { model: "claude-haiku-4-5-20251001", max_tokens: 256, messages: [{ role: "user", content: "Translate: Hello world" }], }, }, // ... up to 10,000 requests ],});// Poll for completionconst result = await client.messages.batches.retrieve(batch.id);console.log(result.processing_status); // "ended" when done
Batch API is ~50% cheaper than individual calls. Good for bulk classification, data extraction, report generation.
Environment setup
BASH
# Install SDKnpm install @anthropic-ai/sdk# Set API keyexport ANTHROPIC_API_KEY=sk-ant-...# Or use .envecho "ANTHROPIC_API_KEY=sk-ant-..." >> .env