TanStack AI
What is TanStack AIโ
TanStack AI is a type-safe, provider-agnostic, framework-agnostic TypeScript SDK for streaming chat, tool calling, structured output, media generation, MCP, and agents. The server talks to a model through an adapter, the client reads the stream through a hook for its framework, and the two halves speak the open AG-UI protocol. There is no hosted platform attached. It is built by the TanStack team behind TanStack Query and TanStack Router.
- Version: 1.0.0, published October 22, 2026 (announcement)
- Stability: 76 packages stable at 1.0; the agent harness is experimental at 0.x
- License: MIT
- Providers: 23 first-party adapters, plus
openaiCompatiblefor any OpenAI-style API - UI frameworks: React, Vue, Solid, Svelte, Preact, Angular, Octane, Remix, and a headless client for vanilla JS
- Community: 3 maintainers, 143 code contributors; AI Project of the Year at the 2026 JavaScript Open Source Awards
- Triage status: stable upstream, not yet used in an Aliz project
We covered the beta in June and the 1.0 release in October. This page is the evaluation summary; the posts have the detail.
Why it's interestingโ
- Stable core with a clear boundary. Every API deprecated in 0.x is gone, and 1.0 added no new concepts. The experimental parts are explicitly versioned 0.x.
- Protocol-first. AG-UI on the wire in both directions, so any AG-UI agent or client (LangGraph, CrewAI, Pydantic AI, a Go service) can sit on the other side of
useChat. - Per-model type safety.
modelOptions, content types, and provider tools are typed from the model you pick. An option the model does not support fails at compile time. - Isomorphic tools.
toolDefinition()once, then.server()or.client(). Approval flows (needsApproval) arrive in the client as typed interrupts. - Owns the hard parts. Persistence, resumable streams, compaction, memory, MCP client and server, sandboxes, Code Mode, and computer use are first-party packages, loaded only when imported.
- Framework-agnostic and platform-free. Eight UI frameworks plus a headless client; runs on Node, edge runtimes, TanStack Start, Next.js, React Router, Remix 3, Express, and React Native.
- Observable and testable. In-app devtools for server and client, OpenTelemetry middleware, and
fakeText()for tests without a network or an API key.
How it fits togetherโ
| Package | Role |
|---|---|
@tanstack/ai | Core: chat(), decide(), streaming, the tool system, agent loop strategies, structured output, adapter types |
@tanstack/ai-client | Headless chat client: message state, transports (SSE, HTTP stream, JSON, WebSocket, XHR), tool execution, approvals |
@tanstack/ai-react and the -vue, -solid, -svelte, -preact, -angular, -octane, -remix packages | useChat and the generation hooks for your framework; createChatHook UI factories under the /ui subpath |
@tanstack/ai-openai and 22 more adapters | One package per provider, tree-shakable per activity (openaiText, openaiImage, ...) |
@tanstack/ai-persistence, @tanstack/ai-mcp, @tanstack/ai-sandbox-*, @tanstack/ai-compaction, @tanstack/ai-memory | Optional capabilities, each its own package |
@tanstack/ai-harness, @tanstack/ai-harness-cli | Long-running agent sessions (experimental, 0.x) |
The server route and the client hook are the whole integration surface for a chat:
import { chat, chatParamsFromRequest, toServerSentEventsResponse } from "@tanstack/ai";
import { openaiText } from "@tanstack/ai-openai";
export async function POST(request: Request) {
const { messages, threadId, runId } = await chatParamsFromRequest(request);
const stream = chat({ adapter: openaiText("gpt-6.1-sol"), messages, threadId, runId });
return toServerSentEventsResponse(stream);
}
import { useChat, fetchServerSentEvents } from "@tanstack/ai-react";
const { messages, sendMessage, isLoading, stop } = useChat({
connection: fetchServerSentEvents("/api/chat"),
threadId: chatId, // required: a stable id per conversation
});
Switching providers is still an import change: anthropicText from @tanstack/ai-anthropic in place of openaiText, with the rest of the code untouched.
Capability mapโ
| Capability | Where | Status |
|---|---|---|
| Streaming chat, tools, agent loop | chat(), useChat, toolDefinition() | Stable |
| Structured output | chat({ outputSchema }), read as final in useChat; Zod, Valibot, ArkType, or JSON Schema | Stable |
| Typed decisions | decide() with choice, score, and boolean questions | Stable |
| Subagents | defineAgent() and chat({ subagents }), rendered as a card part | Stable |
| Tool approval and interrupts | needsApproval, interrupts[].resolveInterrupt() | Stable |
| Persistence and resumable streams | withPersistence middleware, durability adapters; useChat reconnects by itself | Stable |
| MCP client and server | @tanstack/ai-mcp, createMCPServer from @tanstack/ai-mcp/server, WebMCP in both directions | Stable |
| Media | Image, video, audio, speech, transcription, realtime voice, live worlds | Stable |
| Memory and compaction | memoryMiddleware (in-memory, Redis, mem0, Honcho, Hindsight), @tanstack/ai-compaction | Stable |
| Code Mode and computer use | Isolate drivers (Node, QuickJS, Cloudflare, Daytona, E2B); local, Playwright, and sandbox computer drivers | Stable |
| Sandboxes and coding agents | 11 sandbox providers; Claude Code, Codex, OpenCode, Grok Build, and any ACP agent | Stable |
| Agent harness | defineHarness, createHarnessHost, runCli, createHarnessHandler | Experimental (0.x) |
When to useโ
- AI features where provider portability matters: switching models or vendors should be an import change, not a rewrite.
- Backends that are not JavaScript. Anything that emits AG-UI (Python, Go, LangGraph, CrewAI, Pydantic AI) can sit behind
useChat. - Apps that need persistence, reload-safe streaming, or approval flows without hand-built routes.
- Teams already in the TanStack ecosystem (Query, Router, Start, Virtual).
- Projects where compile-time checks on model options and tool schemas are worth the typing discipline.
When NOT to useโ
- Apps that already speak the Vercel UI Message Stream (
@ai-sdk/react, AI Elements, or a backend you do not control). TanStack AI does not read or write that protocol, so moving means rewriting the chat layer. - Anything that depends on the agent harness for a production deadline. It is 0.x, can change in a minor release, and has documented recovery limits.
- Simple single-provider chat where our default Vercel AI SDK plus AI Elements already covers the UI and the team knows it.
- Teams that cannot keep client and server in lockstep. A 1.0 client needs a 1.0 server, and every stable package upgrades together.
Comparison to Vercel AI SDKโ
| TanStack AI | Vercel AI SDK | |
|---|---|---|
| Maturity | Stable 1.0 (October 2026); harness experimental | Stable 7.x (7.0 since June 2026) |
| Ecosystem coupling | None, bring your own backend | Works anywhere, optimized for Vercel/Next.js |
| Protocol | Native AG-UI, in both directions | Own UI Message Stream; AG-UI through an external bridge |
| Type safety | Per model | Per provider |
| Tools | One toolDefinition() with .server() and .client() | tool() on the server, client tools through onToolCall |
| Persistence and resume | Built in | Patterns you write, plus the resumable-stream package |
| Providers | 23 adapters plus openaiCompatible | About 38 first-party provider packages |
| License | MIT | Apache 2.0 |
TanStack's own comparison says to pick TanStack AI for a new app and to stay on the Vercel AI SDK when the app already speaks its protocol. Our Vercel AI SDK page and the AI Assistant Chat cookbook still default to the Vercel SDK. The maturity argument against TanStack AI no longer applies; the familiarity argument for the Vercel SDK still does.
Upgrading from 0.xโ
- Run the upstream codemod. It renames
bodytoforwardedPropsandconversationIdtothreadId. threadIdis required on every chat and generation hook and onchat(). The codemod cannot add it.addToolApprovalResponse()is gone. Resolve thetool-approvalinterrupt instead.ai-react-ui,ai-solid-ui, andai-vue-uihave no 1.0 release. UsecreateChatHookfrom@tanstack/ai-react/ui.- Custom servers end a run with a
RUN_FINISHEDevent, notdata: [DONE]. - Stored chats, runs, and files need the saved-data steps from the upgrade guide before deploy.
Upgrade every stable @tanstack/ai* package together and pin exact versions. The harness packages stay on 0.x.
Details are in the upgrade guide and in the upgrade section of our 1.0 post.
Open questions before it leaves triageโ
- A real project. Nobody at Aliz has shipped on it yet. The first candidate is a chat feature on a React SPA on Cloud Run, where SSE through the load balancer and a persistence store on our usual backends need to be proven.
- Bundle cost. Adapters are tree-shakable per activity. Measure the client bundle of
@tanstack/ai-reactplus@tanstack/ai-clientagainst@ai-sdk/reacton the same UI. - Persistence on our stack.
memoryPersistence()is for development. Check what a Firestore or Postgres store takes to implement against the store reference and its conformance suite. - Overlap with Genkit. The cookbook pairs the Vercel SDK with Firebase Genkit on the server. Decide whether TanStack AI replaces Genkit flows or sits in front of them.
- Harness maturity. Re-evaluate the agent harness when it reaches 1.0.