Anthropic API SDK Node.js Setup Guide
Setting up the Anthropic API SDK in Node.js takes about five minutes if you know the exact steps: install the package, get an API key, instantiate the client, and send your first message. This guide walks through each step, including the parts that trip people up — environment variables, TypeScript types, and streaming setup.
If you just want the fastest path: run npm install @anthropic-ai/sdk, set your API key as an environment variable, create a client instance, and call messages.create(). The rest of this article covers each piece in detail, plus what to do if you don't have direct Anthropic API access yet or want a simpler key-management workflow.
Prerequisites
Before installing anything, make sure you have:
- Node.js 18 or later — the SDK uses modern fetch APIs under the hood
- An API key — either from Anthropic directly, or from a provider that wraps Claude access, like SubToAPI
- npm or yarn — any standard package manager works
Check your Node version with node -v. If you're below 18, upgrade first; the SDK will throw cryptic errors on older runtimes related to missing fetch support.
Step 1: Install the SDK
npm install @anthropic-ai/sdk
Or with yarn:
yarn add @anthropic-ai/sdk
This installs the official TypeScript/JavaScript client, which includes type definitions out of the box — no need for a separate @types package.
Step 2: Store Your API Key
Never hardcode API keys in source files. Use a .env file with a package like dotenv:
npm install dotenv
# .env
ANTHROPIC_API_KEY=your_key_here
Add .env to your .gitignore immediately — committed keys are one of the most common security incidents in small projects.
Step 3: Initialize the Client
import Anthropic from "@anthropic-ai/sdk";
import "dotenv/config";
const client = new Anthropic({
apiKey: process.env.ANTHROPIC_API_KEY,
});
If you omit the apiKey option, the SDK automatically looks for ANTHROPIC_API_KEY in the environment, so this step is optional — but being explicit makes debugging easier when you have multiple keys across environments.
Step 4: Send Your First Request
async function main() {
const message = await client.messages.create({
model: "claude-opus-4",
max_tokens: 1024,
messages: [
{ role: "user", content: "Explain event loops in Node.js in 3 sentences." },
],
});
console.log(message.content[0].text);
}
main();
Run it with node index.js (or tsx index.ts if you're using TypeScript). A successful response returns a message object with a content array, usage metadata, and a stop_reason.
Common Setup Errors
"Module not found" on import — Make sure your package.json has "type": "module" if you're using ES module import syntax, or switch to require() syntax for CommonJS projects.
401 Unauthorized — Double-check the key is loaded correctly. Log process.env.ANTHROPIC_API_KEY (temporarily, never in production) to confirm it's not undefined.
Rate limit errors on first request — New accounts often start with low rate limits. This is normal and increases with usage history and billing tier.
TypeScript type errors on message content — Claude's response content is a union type (text blocks, tool-use blocks, etc.), so you may need to narrow the type before accessing .text:
const block = message.content[0];
if (block.type === "text") {
console.log(block.text);
}
Adding Streaming
For chat interfaces, streaming responses token-by-token improves perceived latency significantly:
const stream = await client.messages.stream({
model: "claude-opus-4",
max_tokens: 1024,
messages: [{ role: "user", content: "Write a haiku about async code." }],
});
stream.on("text", (text) => {
process.stdout.write(text);
});
await stream.finalMessage();
The SDK's .stream() method handles Server-Sent Events parsing internally, so you don't need to manage raw SSE connections yourself.
If You Don't Have Direct Anthropic API Access
Direct API access from Anthropic typically requires a separate application process, usage commitments, and account setup that can take time to get approved, especially for smaller teams or side projects. If you already have Claude access through a subscription and want to start building immediately, SubToAPI turns that access into a standard HTTPS API with the same request shape developers expect.
The setup is nearly identical to the official SDK — you just point requests at a different base URL and use a sub_live_... key:
const response = await fetch("https://api.subtoapi.app/v1/messages", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.SUBTOAPI_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
model: "claude-opus-4",
max_tokens: 1024,
messages: [{ role: "user", content: "Hello, Claude" }],
}),
});
const data = await response.json();
console.log(data.content[0].text);
This approach gives you streaming, tool use, and usage metadata without waiting on a separate enterprise account. Check the quickstart for the full request/response reference, or the messages docs and streaming docs if you're building a chat interface. Plans start at €9/month on the Solo tier, with team seat pricing on pricing for projects with multiple developers sharing API access.
Project Structure Tips
For anything beyond a quick script, separate your client initialization from your call logic:
/src
/lib
anthropic.js // client setup, exported singleton
/services
chat.js // business logic calling the client
index.js // entry point
This keeps API key handling in one place and makes it trivial to swap providers or add retry logic later without touching call sites throughout your codebase.
questions
Do I need a paid Anthropic account to use the Node.js SDK? Yes, the official SDK requires a valid API key tied to a billed Anthropic account. If you only have Claude through a personal subscription, a service like SubToAPI can expose that access as an API instead.
Can I use the SDK in a browser instead of Node.js? Technically yes, but it's not recommended — your API key would be exposed in client-side code. Always call the API from a backend and proxy requests to your frontend.
What Node.js version does the SDK require? Node 18 or later, since the SDK relies on native fetch support that isn't reliably available in earlier versions without polyfills.