Skip to main content

Cloudflare

TanStack AI now ships a first-party Cloudflare adapter, @tanstack/ai-cloudflare. See the Cloudflare adapter page. This page covers Cloudflare's own @cloudflare/tanstack-ai package.

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.

Installation

npm i @cloudflare/tanstack-ai @tanstack/ai
pnpm add @cloudflare/tanstack-ai @tanstack/ai
yarn add @cloudflare/tanstack-ai @tanstack/ai
bun add @cloudflare/tanstack-ai @tanstack/ai

For 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-openrouter
pnpm add @tanstack/ai-openai
pnpm add @tanstack/ai-anthropic
pnpm add @tanstack/ai-gemini
pnpm add @tanstack/ai-grok
pnpm add @tanstack/ai-openrouter
yarn add @tanstack/ai-openai
yarn add @tanstack/ai-anthropic
yarn add @tanstack/ai-gemini
yarn add @tanstack/ai-grok
yarn add @tanstack/ai-openrouter
bun add @tanstack/ai-openai
bun add @tanstack/ai-anthropic
bun add @tanstack/ai-gemini
bun add @tanstack/ai-grok
bun add @tanstack/ai-openrouter

Basic Usage

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);

Workers AI

The simplest way to use AI in a Cloudflare Worker. No API keys needed when using the env.AI binding.

Chat

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);

Chat with REST Credentials

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",
  },
);

Image Generation

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);

Transcription (Speech-to-Text)

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

Text-to-Speech

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);

Summarization

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);

AI Gateway

Route AI requests through Cloudflare's AI Gateway for caching, rate limiting, and unified billing. Supports both Workers AI and third-party providers.

Workers AI through Gateway

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,
  },
);

Third-Party Providers through Gateway

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",
});

Cache Options

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" },
});

Configuration Modes

Workers AI supports four configuration modes:

ModeConfigDescription
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.

Supported Capabilities

ProviderChatSummarizeImage GenTranscriptionTTS
Workers AI✅✅✅✅✅
OpenAI✅✅✅✅✅
Anthropic✅✅❌❌❌
Gemini✅✅✅❌✅
Grok✅✅✅❌❌
OpenRouter✅✅✅❌❌

Environment Variables

For the REST credential path (outside of Cloudflare Workers):

CLOUDFLARE_ACCOUNT_ID=your-account-id
CLOUDFLARE_API_KEY=your-api-key

When using the env.AI binding inside a Worker, no environment variables are needed.

API Reference

Workers AI

  • createWorkersAiChat(model, config) — Chat and structured output
  • createWorkersAiImage(model, config) — Image generation
  • createWorkersAiTranscription(model, config) — Speech-to-text (Whisper, Deepgram)
  • createWorkersAiTts(model, config) — Text-to-speech (Deepgram Aura)
  • createWorkersAiSummarize(model, config) — Summarization (BART-large-CNN)

Gateway Providers

  • createOpenAiChat(model, config) / createOpenAiSummarize / createOpenAiImage / createOpenAiTranscription / createOpenAiTts
  • createAnthropicChat(model, config) / createAnthropicSummarize
  • createGeminiChat(model, config) / createGeminiSummarize / createGeminiImage / createGeminiTts
  • createGrokChat(model, config) / createGrokSummarize / createGrokImage
  • createOpenRouterChat(model, config) / createOpenRouterSummarize / createOpenRouterImage

Next Steps