TokenMix Research Lab · 2026-04-12

AI API for Node.js Developers: Complete Guide to JavaScript and TypeScript AI SDKs (2026)
Node.js and TypeScript developers have first-class AI SDK support from every major provider. The openai npm package works with five or more providers through OpenAI-compatible endpoints. Anthropic's TypeScript SDK is arguably the best-typed AI SDK in any language. Google's SDK handles Gemini integration. This guide covers setup, streaming with async iterators, Express.js integration patterns, and a clear comparison of which provider has the best Node.js SDK. All examples tested with Node.js 20 LTS and TypeScript 5.x by TokenMix.ai in April 2026.
Table of Contents
- [Quick SDK Comparison for Node.js]
- [Prerequisites and Setup]
- [The openai npm Package: One SDK for Multiple Providers]
- [The @anthropic-ai/sdk Package: Claude in TypeScript]
- [The @google/generative-ai Package: Gemini Models]
- [Streaming With Async Iterators in Node.js]
- [Express.js Integration: Building an AI API Server]
- [Tool Calling in Node.js]
- [Structured Output and JSON Parsing]
- [Using TokenMix.ai With the openai Node.js SDK]
- [Full SDK Feature Comparison Table]
- [Cost Comparison for Node.js Applications]
- [Decision Guide: Which Node.js AI SDK Should You Use]
- [Conclusion]
- [FAQ]
Quick SDK Comparison for Node.js
| Feature | openai | @anthropic-ai/sdk | @google/generative-ai |
|---|---|---|---|
| Install | npm install openai |
npm install @anthropic-ai/sdk |
npm install @google/generative-ai |
| TypeScript | Excellent types | Best-in-class types | Good types |
| Streaming | Async iterators | Async iterators | Async iterators |
| Multi-Provider | Yes (base_url) | No (Anthropic only) | No (Google only) |
| Bundle Size | ~200KB | ~150KB | ~100KB |
| ESM + CJS | Both | Both | Both |
| Edge Runtime | Yes | Yes | Yes |
| Auto-Retry | Yes | Yes | Limited |
Prerequisites and Setup
Requirements for this guide:
- Node.js 18+ (20 LTS recommended)
- TypeScript 5.x (optional but strongly recommended)
- An API key from at least one provider
# Create project
mkdir ai-api-node && cd ai-api-node
npm init -y
# Install TypeScript (recommended)
npm install -D typescript @types/node tsx
npx tsc --init
# Install AI SDKs
npm install openai @anthropic-ai/sdk @google/generative-ai
# Set API keys
export OPENAI_API_KEY="sk-your-key"
export ANTHROPIC_API_KEY="sk-ant-your-key"
export GOOGLE_API_KEY="your-google-key"
For TypeScript, set "target": "ES2022" and "module": "NodeNext" in tsconfig.json to enable top-level await and proper ESM support.
The openai npm Package: One SDK for Multiple Providers
The openai package is the most versatile Node.js AI SDK. Full TypeScript support, auto-retries, and works with any OpenAI-compatible provider.
Basic Chat Completion
import OpenAI from "openai";
const client = new OpenAI(); // Uses OPENAI_API_KEY env var
const response = await client.chat.completions.create({
model: "gpt-4.1",
messages: [
{ role: "system", content: "You are a helpful assistant." },
{ role: "user", content: "What is the capital of France?" },
],
});
console.log(response.choices[0].message.content);
// Output: The capital of France is Paris.
Using the Same SDK With DeepSeek
import OpenAI from "openai";
const client = new OpenAI({
apiKey: process.env.DEEPSEEK_API_KEY,
baseURL: "https://api.deepseek.com",
});
const response = await client.chat.completions.create({
model: "deepseek-chat",
messages: [{ role: "user", content: "What is the capital of France?" }],
});
console.log(response.choices[0].message.content);
Using the Same SDK With Groq
import OpenAI from "openai";
const client = new OpenAI({
apiKey: process.env.GROQ_API_KEY,
baseURL: "https://api.groq.com/openai/v1",
});
const response = await client.chat.completions.create({
model: "llama-3.3-70b-versatile",
messages: [{ role: "user", content: "What is the capital of France?" }],
});
console.log(response.choices[0].message.content);
Error Handling in TypeScript
import OpenAI from "openai";
const client = new OpenAI();
try {
const response = await client.chat.completions.create({
model: "gpt-4.1",
messages: [{ role: "user", content: "Hello" }],
});
console.log(response.choices[0].message.content);
} catch (error) {
if (error instanceof OpenAI.RateLimitError) {
console.error("Rate limited. Retry after delay.");
} else if (error instanceof OpenAI.AuthenticationError) {
console.error("Invalid API key.");
} else if (error instanceof OpenAI.APIError) {
console.error(`API error: ${error.status} - ${error.message}`);
} else {
throw error;
}
}
The @anthropic-ai/sdk Package: Claude in TypeScript
Anthropic's TypeScript SDK is the best-typed AI SDK available. Every response type, every parameter, every error -- fully typed with no any types.
Basic Message
import Anthropic from "@anthropic-ai/sdk";
const client = new Anthropic(); // Uses ANTHROPIC_API_KEY env var
const response = await client.messages.create({
model: "claude-sonnet-4-20250514",
max_tokens: 1024,
messages: [{ role: "user", content: "What is the capital of France?" }],
});
if (response.content[0].type === "text") {
console.log(response.content[0].text);
}
Key differences from openai package:
max_tokensis required- System prompt is a separate parameter
- Response uses
response.content[0].textnotresponse.choices[0].message.content - Content blocks are discriminated unions (type-safe)
System Prompt and Prompt Caching
import Anthropic from "@anthropic-ai/sdk";
const client = new Anthropic();
const response = await client.messages.create({
model: "claude-sonnet-4-20250514",
max_tokens: 1024,
system: [
{
type: "text",
text: "You are an expert Node.js developer with 10 years of experience...",
cache_control: { type: "ephemeral" },
},
],
messages: [{ role: "user", content: "How do I set up Express.js?" }],
});
// Cache metrics
console.log(`Input tokens: ${response.usage.input_tokens}`);
console.log(`Cache read: ${response.usage.cache_read_input_tokens}`);
Prompt caching is Anthropic's standout feature. For applications with long system prompts, cached tokens cost 90% less. This makes Claude cost-competitive with much cheaper models for long-context applications.
TypeScript Type Safety Advantage
import Anthropic from "@anthropic-ai/sdk";
const client = new Anthropic();
const response = await client.messages.create({
model: "claude-sonnet-4-20250514",
max_tokens: 1024,
messages: [{ role: "user", content: "Hello" }],
});
// TypeScript narrows content block types
for (const block of response.content) {
switch (block.type) {
case "text":
console.log(block.text); // TypeScript knows this is TextBlock
break;
case "tool_use":
console.log(block.name, block.input); // TypeScript knows this is ToolUseBlock
break;
}
}
The @google/generative-ai Package: Gemini Models
Google's SDK provides access to Gemini models with a straightforward API.
Basic Generation
import { GoogleGenerativeAI } from "@google/generative-ai";
const genAI = new GoogleGenerativeAI(process.env.GOOGLE_API_KEY!);
const model = genAI.getGenerativeModel({ model: "gemini-2.0-flash" });
const result = await model.generateContent("What is the capital of France?");
console.log(result.response.text());
Multi-Turn Chat
const chat = model.startChat();
const result1 = await chat.sendMessage("What is Node.js?");
console.log(result1.response.text());
const result2 = await chat.sendMessage("What are its main advantages?");
console.log(result2.response.text()); // Retains conversation context
Free Tier Usage
Google Gemini's free tier requires no credit card and provides 15 requests/minute for Gemini 2.0 Flash. For Node.js developers prototyping AI features, this is the cheapest path to a working application.
Streaming With Async Iterators in Node.js
Streaming is critical for Node.js web applications. Users expect real-time token delivery, not waiting for the complete response.
Streaming With openai Package
import OpenAI from "openai";
const client = new OpenAI();
const stream = await client.chat.completions.create({
model: "gpt-4.1",
messages: [{ role: "user", content: "Write a haiku about JavaScript." }],
stream: true,
});
for await (const chunk of stream) {
const content = chunk.choices[0]?.delta?.content;
if (content) {
process.stdout.write(content);
}
}
Streaming With @anthropic-ai/sdk
import Anthropic from "@anthropic-ai/sdk";
const client = new Anthropic();
const stream = client.messages.stream({
model: "claude-sonnet-4-20250514",
max_tokens: 1024,
messages: [{ role: "user", content: "Write a haiku about JavaScript." }],
});
for await (const event of stream) {
if (
event.type === "content_block_delta" &&
event.delta.type === "text_delta"
) {
process.stdout.write(event.delta.text);
}
}
Streaming With @google/generative-ai
import { GoogleGenerativeAI } from "@google/generative-ai";
const genAI = new GoogleGenerativeAI(process.env.GOOGLE_API_KEY!);
const model = genAI.getGenerativeModel({ model: "gemini-2.0-flash" });
const result = await model.generateContentStream(
"Write a haiku about JavaScript."
);
for await (const chunk of result.stream) {
process.stdout.write(chunk.text());
}
Express.js Integration: Building an AI API Server
A common pattern: Node.js backend that proxies and enhances AI API calls.
Basic Express.js + Streaming SSE
import express from "express";
import OpenAI from "openai";
const app = express();
app.use(express.json());
const client = new OpenAI();
app.post("/api/chat", async (req, res) => {
const { message } = req.body;
// Set headers for Server-Sent Events
res.setHeader("Content-Type", "text/event-stream");
res.setHeader("Cache-Control", "no-cache");
res.setHeader("Connection", "keep-alive");
try {
const stream = await client.chat.completions.create({
model: "gpt-4.1-mini",
messages: [
{ role: "system", content: "You are a helpful assistant." },
{ role: "user", content: message },
],
stream: true,
});
for await (const chunk of stream) {
const content = chunk.choices[0]?.delta?.content;
if (content) {
res.write(`data: ${JSON.stringify({ content })}\n\n`);
}
}
res.write("data: [DONE]\n\n");
res.end();
} catch (error) {
res.write(`data: ${JSON.stringify({ error: "Stream failed" })}\n\n`);
res.end();
}
});
app.listen(3000, () => console.log("Server running on port 3000"));
Multi-Provider Express.js Pattern
import OpenAI from "openai";
// Create clients for multiple providers
const providers = {
openai: new OpenAI(),
deepseek: new OpenAI({
apiKey: process.env.DEEPSEEK_API_KEY,
baseURL: "https://api.deepseek.com",
}),
groq: new OpenAI({
apiKey: process.env.GROQ_API_KEY,
baseURL: "https://api.groq.com/openai/v1",
}),
tokenmix: new OpenAI({
apiKey: process.env.TOKENMIX_API_KEY,
baseURL: "https://api.tokenmix.ai/v1",
}),
};
// Route by provider
app.post("/api/chat/:provider", async (req, res) => {
const { provider } = req.params;
const client = providers[provider as keyof typeof providers];
// ... rest of handler
});
Tool Calling in Node.js
Tool Calling With openai Package
import OpenAI from "openai";
const client = new OpenAI();
const tools: OpenAI.ChatCompletionTool[] = [
{
type: "function",
function: {
name: "get_weather",
description: "Get current weather for a location",
parameters: {
type: "object",
properties: {
city: { type: "string", description: "City name" },
unit: { type: "string", enum: ["celsius", "fahrenheit"] },
},
required: ["city"],
},
},
},
];
const response = await client.chat.completions.create({
model: "gpt-4.1",
messages: [{ role: "user", content: "What's the weather in London?" }],
tools,
});
const toolCalls = response.choices[0].message.tool_calls;
if (toolCalls) {
for (const call of toolCalls) {
const args = JSON.parse(call.function.arguments);
console.log(`Call: ${call.function.name}(${JSON.stringify(args)})`);
}
}
Tool Calling With @anthropic-ai/sdk
import Anthropic from "@anthropic-ai/sdk";
const client = new Anthropic();
const response = await client.messages.create({
model: "claude-sonnet-4-20250514",
max_tokens: 1024,
tools: [
{
name: "get_weather",
description: "Get current weather for a location",
input_schema: {
type: "object" as const,
properties: {
city: { type: "string", description: "City name" },
},
required: ["city"],
},
},
],
messages: [{ role: "user", content: "What's the weather in London?" }],
});
for (const block of response.content) {
if (block.type === "tool_use") {
console.log(`Tool: ${block.name}, Input: ${JSON.stringify(block.input)}`);
}
}
Structured Output and JSON Parsing
JSON Mode With openai Package
import OpenAI from "openai";
const client = new OpenAI();
const response = await client.chat.completions.create({
model: "gpt-4.1",
messages: [
{
role: "system",
content: "Return JSON with keys: name, population, continent",
},
{ role: "user", content: "Tell me about Japan" },
],
response_format: { type: "json_object" },
});
const data = JSON.parse(response.choices[0].message.content!);
console.log(data);
// { name: "Japan", population: 125000000, continent: "Asia" }
Type-Safe Parsing With Zod
import OpenAI from "openai";
import { z } from "zod";
const CountrySchema = z.object({
name: z.string(),
population: z.number(),
continent: z.string(),
});
const client = new OpenAI();
const response = await client.chat.completions.create({
model: "gpt-4.1",
messages: [
{ role: "system", content: "Return JSON: {name, population, continent}" },
{ role: "user", content: "Tell me about Japan" },
],
response_format: { type: "json_object" },
});
const parsed = CountrySchema.safeParse(
JSON.parse(response.choices[0].message.content!)
);
if (parsed.success) {
console.log(parsed.data.name); // TypeScript knows this is string
} else {
console.error("Invalid response:", parsed.error);
}
Using TokenMix.ai With the openai Node.js SDK
TokenMix.ai integrates with the standard openai npm package. One base URL change gives you access to every provider.
import OpenAI from "openai";
const client = new OpenAI({
apiKey: process.env.TOKENMIX_API_KEY,
baseURL: "https://api.tokenmix.ai/v1",
});
// Access any model from any provider
const models = ["gpt-4.1", "claude-sonnet-4", "deepseek-chat", "gemini-2.0-flash"];
for (const model of models) {
const response = await client.chat.completions.create({
model,
messages: [{ role: "user", content: "Hello from Node.js" }],
});
console.log(`${model}: ${response.choices[0].message.content}`);
}
This pattern is ideal for Node.js applications that need to route between models based on the task. TokenMix.ai handles provider authentication, rate limits, and failover behind the scenes.
Full SDK Feature Comparison Table
| Feature | openai (npm) | @anthropic-ai/sdk | @google/generative-ai |
|---|---|---|---|
| TypeScript quality | Excellent | Best-in-class | Good |
| Chat completions | Yes | Yes (messages API) | Yes (generateContent) |
| Streaming | Async iterators | Event stream + helpers | Async iterators |
| Tool calling | Yes | Yes | Yes |
| JSON mode | Yes | Via tool_choice | Yes |
| Vision/images | Yes | Yes | Yes |
| Embeddings | Yes | No (use Voyage) | Yes |
| Prompt caching | Automatic | Manual (best) | Context caching |
| Batch API | Yes | Yes | No |
| Auto-retry | Yes (configurable) | Yes (configurable) | Limited |
| Edge runtime | Yes | Yes | Yes |
| ESM + CJS | Both | Both | Both |
| Bundle size | ~200KB | ~150KB | ~100KB |
| Multi-provider | Yes (base_url) | No | No |
| Vercel AI SDK compat | Yes | Yes (via adapter) | Yes (via adapter) |
Cost Comparison for Node.js Applications
| Application Type | Monthly Requests | Avg Tokens | Best Model | Monthly Cost |
|---|---|---|---|---|
| Personal API/bot | 5,000 | 800 | Gemini Flash (free) | $0 |
| Express.js prototype | 20,000 | 1,200 | GPT-4.1 mini | $21 |
| Next.js SaaS app | 100,000 | 1,500 | GPT-4.1 mini |