The Cloudflare adapter provides access to Cloudflare Workers AI models and AI Gateway for routing requests to OpenAI, Anthropic, Gemini, Grok, and OpenRouter with caching, rate limiting, and unified billing.
npm i @cloudflare/tanstack-ai @tanstack/aipnpm add @cloudflare/tanstack-ai @tanstack/aiyarn add @cloudflare/tanstack-ai @tanstack/aibun add @cloudflare/tanstack-ai @tanstack/aiFor AI Gateway with third-party providers, install the provider SDKs you need:
npm i @tanstack/ai-openai
npm i @tanstack/ai-anthropic
npm i @tanstack/ai-gemini
npm i @tanstack/ai-grok
npm i @tanstack/ai-openrouterpnpm add @tanstack/ai-openai
pnpm add @tanstack/ai-anthropic
pnpm add @tanstack/ai-gemini
pnpm add @tanstack/ai-grok
pnpm add @tanstack/ai-openrouteryarn add @tanstack/ai-openai
yarn add @tanstack/ai-anthropic
yarn add @tanstack/ai-gemini
yarn add @tanstack/ai-grok
yarn add @tanstack/ai-openrouterbun add @tanstack/ai-openai
bun add @tanstack/ai-anthropic
bun add @tanstack/ai-gemini
bun add @tanstack/ai-grok
bun add @tanstack/ai-openrouterimport { chat, toHttpResponse } from "@tanstack/ai";
import { createWorkersAiChat } from "@cloudflare/tanstack-ai";
import { env } from "./env";
const adapter = createWorkersAiChat(
"@cf/meta/llama-4-scout-17b-16e-instruct",
{ binding: env.AI },
);
const response = chat({
adapter,
stream: true,
messages: [{ role: "user", content: "Hello!" }],
});
const httpResponse = toHttpResponse(response);The simplest way to use AI in a Cloudflare Worker. No API keys needed when using the env.AI binding.
import { chat, toHttpResponse } from "@tanstack/ai";
import { createWorkersAiChat } from "@cloudflare/tanstack-ai";
import { env } from "./env";
const adapter = createWorkersAiChat(
"@cf/meta/llama-4-scout-17b-16e-instruct",
{ binding: env.AI },
);
const response = chat({
adapter,
stream: true,
messages: [{ role: "user", content: "Hello!" }],
});
const httpResponse = toHttpResponse(response);If you're not running inside a Worker, use account ID and API key instead:
import { createWorkersAiChat } from "@cloudflare/tanstack-ai";
const adapter = createWorkersAiChat(
"@cf/meta/llama-4-scout-17b-16e-instruct",
{
accountId: "your-account-id",
apiKey: "your-api-key",
},
);import { generateImage } from "@tanstack/ai";
import { createWorkersAiImage } from "@cloudflare/tanstack-ai";
import { env } from "./env";
const adapter = createWorkersAiImage(
"@cf/stabilityai/stable-diffusion-xl-base-1.0",
{ binding: env.AI },
);
const result = await generateImage({
adapter,
prompt: "a cat in space",
});
console.log(result.images[0]?.b64Json);Supports Whisper and Deepgram models:
import { generateTranscription } from "@tanstack/ai";
import { createWorkersAiTranscription } from "@cloudflare/tanstack-ai";
import { env, audioArrayBuffer } from "./env";
const adapter = createWorkersAiTranscription(
"@cf/openai/whisper-large-v3-turbo",
{ binding: env.AI },
);
const result = await generateTranscription({
adapter,
audio: audioArrayBuffer,
});
console.log(result.text);
console.log(result.segments);Supported transcription models: @cf/openai/whisper, @cf/openai/whisper-tiny-en, @cf/openai/whisper-large-v3-turbo, @cf/deepgram/nova-3
import { generateSpeech } from "@tanstack/ai";
import { createWorkersAiTts } from "@cloudflare/tanstack-ai";
import { env } from "./env";
const adapter = createWorkersAiTts("@cf/deepgram/aura-2-en", {
binding: env.AI,
});
const result = await generateSpeech({
adapter,
text: "Hello world",
});
console.log(result.audio);import { summarize, type AnySummarizeAdapter } from "@tanstack/ai";
import { createWorkersAiSummarize } from "@cloudflare/tanstack-ai";
import { env } from "./env";
const adapter: AnySummarizeAdapter = createWorkersAiSummarize("@cf/facebook/bart-large-cnn", {
binding: env.AI,
});
const result = await summarize({
adapter,
text: "Long article here...",
});
console.log(result.summary);Route AI requests through Cloudflare's AI Gateway for caching, rate limiting, and unified billing. Supports both Workers AI and third-party providers.
import { createWorkersAiChat } from "@cloudflare/tanstack-ai";
import { env } from "./env";
const adapter = createWorkersAiChat(
"@cf/meta/llama-4-scout-17b-16e-instruct",
{
binding: env.AI.gateway("my-gateway-id"),
apiKey: env.WORKERS_AI_TOKEN,
},
);Use the binding approach (recommended for Cloudflare Workers):
import {
createOpenAiChat,
createAnthropicChat,
createGeminiChat,
createGrokChat,
createOpenRouterChat,
} from "@cloudflare/tanstack-ai";
import { env } from "./env";
const openai = createOpenAiChat("gpt-4o", {
binding: env.AI.gateway("my-gateway-id"),
});
const anthropic = createAnthropicChat("claude-sonnet-4-5", {
binding: env.AI.gateway("my-gateway-id"),
});
const grok = createGrokChat("grok-4.3", {
binding: env.AI.gateway("my-gateway-id"),
});
const openrouter = createOpenRouterChat("openai/gpt-4o", {
binding: env.AI.gateway("my-gateway-id"),
});Or use credentials for non-Worker environments:
import { createOpenAiChat } from "@cloudflare/tanstack-ai";
const adapter = createOpenAiChat("gpt-4o", {
accountId: "your-account-id",
gatewayId: "your-gateway-id",
cfApiKey: "your-cf-api-key",
apiKey: "provider-api-key",
});Both binding and credentials modes support cache configuration:
import { createOpenAiChat } from "@cloudflare/tanstack-ai";
import { env } from "./env";
const adapter = createOpenAiChat("gpt-4o", {
binding: env.AI.gateway("my-gateway-id"),
skipCache: false,
cacheTtl: 3600,
customCacheKey: "my-key",
metadata: { user: "test" },
});Workers AI supports four configuration modes:
| Mode | Config | Description |
|---|---|---|
| Plain binding | { binding: env.AI } | Direct access, no gateway |
| Plain REST | { accountId, apiKey } | REST API, no gateway |
| Gateway binding | { binding: env.AI.gateway(id) } | Through AI Gateway via binding |
| Gateway REST | { accountId, gatewayId, ... } | Through AI Gateway via REST |
Third-party providers (OpenAI, Anthropic, Gemini, Grok, OpenRouter) only support the gateway modes.
| Provider | Chat | Summarize | Image Gen | Transcription | TTS |
|---|---|---|---|---|---|
| Workers AI | ✅ | ✅ | ✅ | ✅ | ✅ |
| OpenAI | ✅ | ✅ | ✅ | ✅ | ✅ |
| Anthropic | ✅ | ✅ | ❌ | ❌ | ❌ |
| Gemini | ✅ | ✅ | ✅ | ❌ | ✅ |
| Grok | ✅ | ✅ | ✅ | ❌ | ❌ |
| OpenRouter | ✅ | ✅ | ✅ | ❌ | ❌ |
For the REST credential path (outside of Cloudflare Workers):
CLOUDFLARE_ACCOUNT_ID=your-account-id
CLOUDFLARE_API_KEY=your-api-keyWhen using the env.AI binding inside a Worker, no environment variables are needed.