Skip to content
Learni
View all tutorials
Intelligence Artificielle

How to Integrate the Claude API in Node.js in 2026

Lire en français

Introduction

In 2026, Claude from Anthropic leads professional AI use cases with its superior reasoning, built-in safety, and top performance on Claude 3.5 Sonnet. Unlike GPT models, Claude shines in complex tasks like code generation or long document analysis, handling up to 200k tokens of context. This intermediate tutorial guides you through integrating the Claude API into a Node.js app using TypeScript. You'll build a robust client, manage conversations, stream responses, and implement custom tools. Ideal for chatbots, autonomous agents, or backend APIs. By the end, you'll have a fully functional server ready to deploy on Vercel, complete with error handling and rate limiting. Why choose Claude? Fewer hallucinations and strong ethical alignment—perfect for enterprises.

Prerequisites

  • Node.js 20+ installed
  • Anthropic account with API key (free for testing: console.anthropic.com)
  • Knowledge of TypeScript and async/await
  • npm or yarn
  • Editor like VS Code with TypeScript extension

SDK Installation and Project Setup

terminal
mkdir claude-node-app
cd claude-node-app
npm init -y
npm install @anthropic-ai/sdk typescript @types/node dotenv
npm install -D tsx
tsc --init
npm pkg set type=module

This script sets up a modern Node.js project with the official Anthropic SDK. tsx lets you run TypeScript directly without compilation. dotenv handles secrets. Avoid older SDK versions that lack tool support.

Environment Variables Setup

.env
ANTHROPIC_API_KEY=sk-ant-api03-abcdefghijklmnopqrstuvwxyz1234567890
MODEL=claude-3-5-sonnet-20240620
MAX_TOKENS=1024
TEMPERATURE=0.7

Copy this .env file to your project root. Replace the key with yours from the Anthropic console. MAX_TOKENS controls costs; TEMPERATURE adjusts creativity (0 = deterministic). Never commit .env to Git—add it to .gitignore.

First API Call

Now, let's test a simple message. Think of Claude as an expert consultant: give it a brief, and it responds precisely. This first example validates your setup and measures latency (typically <2s).

Basic Client for a Single Message

basic-client.ts
import Anthropic from '@anthropic-ai/sdk';
import 'dotenv/config';

const client = new Anthropic({
  apiKey: process.env.ANTHROPIC_API_KEY!,
});

async function simpleMessage() {
  const msg = await client.messages.create({
    model: process.env.MODEL!,
    max_tokens: parseInt(process.env.MAX_TOKENS!),
    temperature: parseFloat(process.env.TEMPERATURE!),
    messages: [{ role: 'user', content: 'Explique en 3 points les avantages de Claude vs GPT-4.' }],
  });
  console.log(msg.content[0].text);
}

simpleMessage().catch(console.error);

This code creates a client and sends a user message. Extract the response from content[0].text. Use ! for TypeScript assertions on env vars. Test with npx tsx basic-client.ts—expect a structured 3-point response.

Handling Multi-Turn Conversations

For a realistic chatbot, maintain history like a conversation thread. Each turn appends user/assistant messages, preserving context without exceeding 200k tokens.

Conversational Chat with History

chat-client.ts
import Anthropic from '@anthropic-ai/sdk';
import 'dotenv/config';

type Message = { role: 'user' | 'assistant'; content: string };

const client = new Anthropic({ apiKey: process.env.ANTHROPIC_API_KEY! });
const messages: Message[] = [];

async function chat(userInput: string) {
  messages.push({ role: 'user', content: userInput });
  const response = await client.messages.create({
    model: process.env.MODEL!,
    max_tokens: 1024,
    messages: messages.map(m => ({ role: m.role, content: m.content })),
  });
  const aiReply = response.content[0].text;
  messages.push({ role: 'assistant', content: aiReply });
  console.log('Claude:', aiReply);
  return aiReply;
}

// Exemple d'usage
chat('Développe un hook React pour fetcher des données.').catch(console.error);

The messages array simulates a persistent session. Map it for the API call. This naturally handles context. Limit history to 10 turns to control costs: messages.slice(-10). Run multiple chat() calls to test.

Streaming Implementation for Smooth UX

stream-client.ts
import Anthropic from '@anthropic-ai/sdk';
import 'dotenv/config';

const client = new Anthropic({ apiKey: process.env.ANTHROPIC_API_KEY! });

async function streamChat(prompt: string) {
  const stream = await client.messages.stream({
    model: process.env.MODEL!,
    max_tokens: 1024,
    messages: [{ role: 'user', content: prompt }],
    stream_mode: 'values',
  });

  let fullResponse = '';
  for await (const item of stream) {
    const delta = item.delta?.content?.[0]?.text || '';
    process.stdout.write(delta);
    fullResponse += delta;
  }
  console.log('\n--- Fin ---');
  return fullResponse;
}

streamChat('Génère un poème sur l\'IA en français.').catch(console.error);

Streaming with stream_mode: 'values' displays tokens in real-time, perfect for React UIs. Accumulate fullResponse for logging. process.stdout.write simulates a live terminal. Rate limits: 50 RPM on Sonnet—handle retries.

Adding Tools for Intelligent Agents

Tools turn Claude into a true agent: it calls your functions (e.g., weather, DB query) via JSON schema. Like an orchestrator, it decides when to use them.

Client with Custom Tools

tools-client.ts
import Anthropic from '@anthropic-ai/sdk';
import 'dotenv/config';

const client = new Anthropic({ apiKey: process.env.ANTHROPIC_API_KEY! });

const tools = [
  {
    name: 'get_weather',
    description: 'Récupère la météo d\'une ville',
    inputSchema: {
      type: 'object',
      properties: { city: { type: 'string' } },
      required: ['city'],
    },
  },
];

function getWeather(city: string): string {
  return `À ${city}, il fait 22°C, ensoleillé.`; // Mock
}

async function agentWithTools(prompt: string) {
  let messages = [{ role: 'user', content: prompt }];
  let toolCalls = true;
  while (toolCalls) {
    const msg = await client.messages.create({
      model: process.env.MODEL!,
      max_tokens: 1024,
      messages,
      tools,
    });
    const text = msg.content[0].text || '';
    console.log('Claude:', text);
    const toolCall = msg.content.find((c: any) => c.type === 'tool_use');
    if (toolCall) {
      const args = JSON.parse(toolCall.input);
      const result = getWeather(args.city);
      messages.push({ role: 'user', content: [{ type: 'tool_result', tool_use_id: toolCall.id, content: result }] });
    } else {
      toolCalls = false;
    }
  }
}

agentWithTools('Quelle est la météo à Paris ?').catch(console.error);

Define tools with strict JSON schema. Loop until no more tool calls. Respond with tool_result. Mocked here; integrate real fetches. Claude automatically parses args—robust against JSON errors.

Next.js API Route with Claude

app/api/claude/route.ts
import Anthropic from '@anthropic-ai/sdk';
import { NextRequest, NextResponse } from 'next/server';

const client = new Anthropic({ apiKey: process.env.ANTHROPIC_API_KEY! });

export async function POST(req: NextRequest) {
  try {
    const { messages } = await req.json();
    const response = await client.messages.create({
      model: process.env.MODEL!,
      max_tokens: 1024,
      messages,
    });
    return NextResponse.json({ content: response.content[0].text });
  } catch (error) {
    return NextResponse.json({ error: 'Erreur API Claude' }, { status: 500 });
  }
}

For Next.js 15+, this App Router handles POST /api/claude with body {messages: [...]}. Try/catch catches rate limits (429). Deploy on Vercel: env vars auto-propagate. Test with curl or frontend fetch.

Best Practices

  • Rate limiting: Use upstash-redis for 50 RPM on Sonnet; retry with exponential backoff (e.g., 1s, 2s, 4s).
  • Security: Validate inputs with Zod before sending; cap max_tokens at 4k.
  • Caching: Cache identical responses with Redis (key: sha256(prompt)). Save 70% on costs.
  • Monitoring: Log token usage (usage in response) with Sentry.
  • Models: Sonnet for general use; Opus for expert tasks (more expensive).

Common Errors to Avoid

  • Context overload: Too-long history → auto-truncation, lost coherence. Slice to 8k tokens.
  • No streaming: Latency >5s hurts UX. Always stream in production.
  • Poor tool schemas: Invalid JSON → Claude fails. Validate with Ajv.
  • Env not loaded: Import dotenv/config first. Causes 401 errors.
  • No fallback: If Claude is down, switch to GPT via dynamic config.

Next Steps

Master multi-tool agents with Claude Projects. Check the Anthropic docs. Advanced AI training: Learni Group Courses. Open-source project: fork anthropic-sdk-examples.