Skip to content
Getting Started

Overview

TanStack AI is a TypeScript SDK for streaming chat, tool calls, and media generation. Swap the provider or the UI framework without rewriting the call.

TanStack AI gives you one typed API for all of that. Your server talks to the provider through an adapter. Your UI reads the stream through a hook for your framework.

Start here: Quick Start. You get a streaming chat in about 5 minutes.

Who it is for

What you get

  • Type safety. Tool inputs, model options, and message parts are typed from your schemas and the model you pick.
  • Streaming. Responses stream token by token, from the server route to the UI.
  • Isomorphic tools. Define a tool once with toolDefinition(). Run it on the server with .server() or in the browser with .client().
  • Any provider. OpenRouter, OpenAI, Anthropic, Gemini, Ollama, and more. Swap the adapter, keep the code.
  • Any framework. React, Vue, Solid, Svelte, Preact, Angular, Octane, Remix, or no framework.

Later, when you need them:

  • Approvals. Pause a tool call until a person says yes. See Tool Approval.
  • Typed decisions. Ask choice, score, and boolean questions with decide(). See Evaluate.
  • Bring your own key. Users paste their own provider key in the browser. See Bring Your Own Key.

How it works

A chat has two halves:

  1. The server calls chat() with an adapter and the messages. It returns the stream as a Response.
  2. The client calls a hook such as useChat(). The hook sends messages to your server route and renders the parts as they arrive.

Tools fit into the same loop. When the model calls a tool, TanStack AI runs it, sends the result back to the model, and keeps streaming.

ts
import { chat, toolDefinition } from '@tanstack/ai'
import { openaiText } from '@tanstack/ai-openai'
import { z } from 'zod'

const products = [
  { id: '1', name: 'Blue mug' },
  { id: '2', name: 'Red mug' },
]

const getProductsDef = toolDefinition({
  name: 'getProducts',
  description: 'Search for products by query',
  inputSchema: z.object({ query: z.string() }),
  outputSchema: z.array(z.object({ id: z.string(), name: z.string() })),
})

const getProducts = getProductsDef.server(async ({ query }) =>
  products.filter((product) => product.name.toLowerCase().includes(query)),
)

const stream = chat({
  adapter: openaiText('gpt-6.1-sol'),
  messages: [{ role: 'user', content: 'Find mugs' }],
  threadId: 'thread-1',
  tools: [getProducts],
})

Learn by building

Each tutorial builds one small app from start to finish:

Reference

Where it runs

The core works in any JavaScript runtime. These hosts are common:

HostNotes
TanStack StartReact Start or Solid Start.
Next.jsAPI routes and App Router.
React Router v7Loaders and actions.
Remix 3Controllers return SSE. Call createChat in a clientEntry island.
ExpressNode.js server. See Quick Start: Server Only.
React Native / ExpouseChat with an absolute server URL and an XHR transport. See Quick Start: React Native.

Core packages

PackageWhat it does
@tanstack/aiThe core. chat(), streaming, the tool system, agent loop strategies, and adapter types. Model options and content types (text, image, audio, video, document) are typed per model.
@tanstack/ai-clientA headless chat client for any framework. It holds message state, streams through connection adapters (SSE, HTTP stream, custom), runs server and client tools, and handles approvals.
@tanstack/ai-reactuseChat for React, with approvals and typed messages through InferChatMessages.
@tanstack/ai-soliduseChat for Solid, with the same features as React.
@tanstack/ai-octaneuseChat for Octane, with the same hook names as @tanstack/ai-react. The Octane plugin compiles it from .tsrx source.

Vue, Svelte, Preact, Angular, and Remix have their own packages too. See the API reference for each one.

Provider adapters

Each adapter is its own package. Install only the ones you use.

PackageProvider
@tanstack/ai-openrouterOpenRouter. 300+ models with one API key. A good first pick.
@tanstack/ai-openaiOpenAI (GPT models).
@tanstack/ai-anthropicAnthropic (Claude).
@tanstack/ai-geminiGoogle Gemini.
@tanstack/ai-vertexGemini on Google Vertex AI. For Claude, Grok, and Mistral on Vertex, use @tanstack/ai-anthropic/vertex, @tanstack/ai-grok/vertex, and @tanstack/ai-mistral/vertex.
@tanstack/ai-ollamaOllama (local models).
@tanstack/ai-groqGroq.
@tanstack/ai-grokxAI Grok.
@tanstack/ai-bedrockAmazon Bedrock (Claude, Nova, Llama, and more through AWS).
@tanstack/ai-byteplusBytePlus (Seed chat, Seedance video, Seedream image, Seed Speech).
@tanstack/ai-falfal (image and video generation).
@tanstack/ai-reactorReactor (live world and video generation: Orbis, Happy Oyster, LingBot, Helios, FastH3).
@tanstack/ai-worldlabsWorld Labs Marble (persistent 3D world generation).
@tanstack/ai-llmgatewayLLM Gateway. Hundreds of models through one OpenAI-compatible endpoint. You can host it yourself.
@tanstack/ai-cloudflareCloudflare Workers AI (chat, embeddings, image, speech, transcription, evaluate) and AI Gateway routing.
@tanstack/ai-typesafeTypeSafe Jev (typed evaluate decisions).
@tanstack/ai-ollayaLocal Ollaya laya models for typed evaluate decisions. No API key.
@tanstack/ai-lovableLovable AI Gateway (Google and OpenAI chat, image, video, embeddings, and speech through one project key).

The Adapters section of the sidebar has a page for each provider.