DEV Community

MUHAMMAD ZAIN UL ABIDIN
MUHAMMAD ZAIN UL ABIDIN

Posted on Originally published at zainvibes.com

TanStack AI vs Vercel AI SDK: The One I Would Ship

I installed both SDKs this morning and read what they actually export. The ai package is at 7.0.159 and exposes 181 top-level exports; @tanstack/ai is at 1.0.1 with 205. Under the marketing, both do the same job: one typed API over every model provider. What differs is three architectural bets - the wire protocol, how far the types reach, and what happens to a run when your server restarts. Those bets, not the feature lists, are what you will live with. So I compared those.

The short answer

For a production Next.js app shipping this quarter, I would still start with the Vercel AI SDK - version 7, released June 25, 2026. It is the more battle-tested system: more than 16 million weekly downloads by Vercel's own count, a deeper observability stack, first-class timeouts, and the only GA durable-agent story of the two. TanStack AI 1.0, released October 23, 2026, is the better-designed abstraction in several places I care about - per-model typing, isomorphic tools, an open wire protocol - and it is the pick when your app is not Next.js-shaped or when owning the protocol matters more than ecosystem gravity. The rest of this post is the evidence, axis by axis, so you can overrule me with your own constraints.

How I checked this

I did not compare landing pages. I pulled both packages from npm on November 2, 2026, installed them side by side, and inspected the installed artifacts: version numbers, engines fields, dependency trees, and full export surfaces. I read Vercel's AI SDK 7 announcement and TanStack's 1.0 post end to end, plus TanStack's own comparison and migration docs. Where a claim below comes from a vendor's own comparison page, I treat it as their positioning, not neutral fact, and I say so. Where it comes from the installed packages, you can reproduce it with one npm i and a text editor. One limit, stated plainly: I did not run live model calls for this comparison, because the differences that matter here are architectural, and architecture is visible in the type surface before the first token streams.

The core APIs look alike. The bets underneath do not.

At the call site, the two SDKs are nearly interchangeable, and TanStack's migration doc maps them line for line. streamText() becomes chat(). generateText() becomes chat({ stream: false }). generateObject() becomes chat({ outputSchema }). If the APIs rhyme this closely, why does the choice matter? Because everything around the call site diverges: what travels over the wire, what the compiler knows, and which platform, if any, the SDK is quietly recruiting you into.

// Vercel AI SDK 7: the model is a value, the loop is an option
import { streamText, tool, stepCountIs } from 'ai';
import { openai } from '@ai-sdk/openai';

const result = streamText({
  model: openai('gpt-5'),
  tools: { weather: tool({ /* ... */ }) },
  stopWhen: stepCountIs(5),
});
Enter fullscreen mode Exit fullscreen mode
// TanStack AI 1.0: the adapter is the value, the loop is a strategy
import { chat, toServerSentEventsResponse } from '@tanstack/ai';
import { openaiText } from '@tanstack/ai-openai';

const stream = chat({
  adapter: openaiText('gpt-6.1-sol'),
  messages,
  threadId,
  agentLoopStrategy: maxIterations(5),
});

return toServerSentEventsResponse(stream);
Enter fullscreen mode Exit fullscreen mode

Two details in that small diff tell you a lot. The AI SDK's core package depends on @ai-sdk/gateway directly - the Vercel AI Gateway ships inside the core's dependency tree, and a bare string model id like 'openai/gpt-5' resolves through it. The default path and the platform path are the same path. TanStack's core instead depends on @ag-ui/core: the protocol is the dependency, not a gateway. Neither is sinister. Both are honest signals about what each project optimizes for when you are not looking.

The wire protocol is the real fork

Your server and your client have to agree on a stream format, and that agreement outlives every other decision in this post. TanStack AI streams AG-UI, an open protocol with typed events for text deltas, tool calls, state patches, and run lifecycle, running in both directions. Any AG-UI client can sit in front of your backend, and any AG-UI agent can sit behind your UI. The AI SDK streams its own UI Message Stream protocol: mature, well-tooled, and spoken natively by exactly one ecosystem - @ai-sdk/react, AI Elements, and a large pile of tutorials and templates. AG-UI reaches the AI SDK only through an external bridge package.

Here is how I think about the cost. Provider abstractions are cheap to swap because they sit behind your own route handler. Protocols are expensive to swap because they leak into the client: message part rendering, tool approval UI, resumable stream handling, even your persisted chat history format. TanStack's own docs make the honest version of this point: stay on the AI SDK if your app already speaks its protocol, because TanStack AI does not read or write it. I agree with their framing, and it cuts both ways. Picking the AI SDK today means your frontend is written against a vendor protocol. Picking TanStack means betting that an open protocol with a smaller current ecosystem keeps growing. For a greenfield app, I price the open protocol as worth real money. For an app with a working AI SDK frontend, the migration math in the section below usually ends the discussion.

Type safety: per provider versus per model

Both SDKs take TypeScript seriously, which is rarer than it should be in this space. The AI SDK types your tool inputs from a Zod schema (v7 accepts Zod 3.25+ or Zod 4, or any Standard Schema validator), types UI message parts so isToolUIPart(part) narrows rendering, and gives each provider package its own option types. That is a strong surface, and I have no complaints about it at the level most apps touch.

TanStack goes one level deeper, at the model. Pick a model and the adapter narrows your options to what that model supports: reasoning controls, content types, and generation parameters are typed per model, so passing an option the model does not have is a compile error rather than a silent no-op or a runtime rejection. They also type the client side harder than most: InferChatMessages derives your useChat message types from your server definition, so a renamed tool output field breaks the UI build instead of rendering undefined at runtime. The AI SDK gets you partway there with generic UIMessage types you parameterize by hand.

My judgment: for tool inputs and message shapes, call it even. For model options - the surface where provider differences actually bite, where one model takes reasoning effort and another takes a thinking budget - per-model typing is the design I wish every SDK had. It is the single most senior-friendly decision in TanStack's API.

Tools and agent loops: where the loop lives

A tool definition looks similar in both, until you ask where the tool runs. The AI SDK's tool() defines a server tool with an execute function; client-side tools are handled separately, through the chat transport and onToolCall on the client. TanStack's toolDefinition() defines the schema once and attaches execution with .server(fn) or .client(fn) - isomorphic tools are a first-class concept, not a pattern. If your product has tools that genuinely live on both sides (a "highlight this row" client tool next to a "charge the card" server tool), TanStack's model will feel like it was designed by someone who shipped that product. Because it probably was.

The loop itself: the AI SDK gives you stopWhen conditions (stepCountIs, hasToolCall, or your own function) on generateText/streamText, and a ToolLoopAgent class when you want the loop as a reusable object with its own instructions, tools, and typed runtime context. TanStack gives you agentLoopStrategy: a function from loop state to boolean, with maxIterations(n) and untilFinishReason(...) as the built-ins, and createChatOptions to share one loop configuration between server calls and the harness. Functionally these are the same machine. The difference is packaging: Vercel is converging on an Agent class hierarchy (ToolLoopAgent, WorkflowAgent, HarnessAgent), TanStack on composable functions and strategies. I prefer functions for testability; teams that think in objects will prefer the classes. Neither preference should decide this for you.

Approvals are where v7 quietly pulls ahead on rigor. Both SDKs gate a tool behind human approval - needsApproval per tool exists in both, and TanStack adds batched approvals and interrupt-based resumption. But AI SDK 7 adds approval policies as functions (auto-approve, auto-deny, escalate) and, for high-risk flows, opt-in HMAC-signed approvals: the approved tool inputs are cryptographically bound to the approval token, and inputs and policies are revalidated before the run resumes. If your agent can move money, merge code, or delete data, that is not decoration. That is the control your auditor will ask about.

Structured output: a result versus a message part

Ask each SDK for JSON and you get a philosophical difference. The AI SDK treats structured output as a result you await: generateObject, streamObject, or the newer Output.object() on a text call, with partial results streaming as the object fills in. TanStack treats it as a message part: chat({ outputSchema }) streams a typed object into the conversation, alongside text and tool calls, and it stays in the history like any other part. Under the hood both parse partial JSON as it arrives - the AI SDK exports parsePartialJson, and @tanstack/ai depends on a partial-json parser; the mechanics are the same.

Which model is right depends on what the object is. If the object is the end of the interaction - an extraction, a classification, a form fill - the result model is cleaner and the AI SDK's version is the more mature one, with dedicated error types like NoObjectGeneratedError when the model fails to produce valid output. If the object is a step inside a longer conversation - a table the user keeps refining with the model - TanStack's part model saves you from bolting a side channel onto your message history. Know which of the two your product actually does before you let this axis sway you.

Durability: the question that decides this in 2027

An in-memory agent loop has a simple failure mode: the process restarts, the run is gone. Both projects know agents are outgrowing request-scoped loops, and both shipped an answer in the last five months. The answers are not equivalent, and this is the axis where I see the most confused takes.

Vercel's answer is WorkflowAgent in @ai-sdk/workflow. Execution state persists to durable storage between steps, so a run survives deploys, process restarts, interruptions, and approvals that take hours. It is GA, it is the most complete durability story in TypeScript AI today, and the price is written in the import: your agent now runs on the Workflow SDK's execution model, with its directives and its platform assumptions. Durable, yes. Portable, no.

TanStack's answer comes in two layers. The 1.0 core has a detachable run model - detach a run, journal it, let another process take it over, reap orphans - designed to work on any of its 11 sandbox providers rather than one platform's workflow engine. On top of that, the new @tanstack/ai-harness adds durable sessions: a session log per thread, waits for approvals that survive restarts, mid-turn steering. But the harness ships at 0.x, explicitly experimental, and TanStack's own 1.0 post links to its recovery limits, including child-agent waits held in memory that do not resume across hosts. I respect the honesty. I would not yet bet a billing-critical agent on it.

So the durability verdict is asymmetric. Need durable agents in production now: AI SDK plus Workflow, eyes open about the lock-in. Need runs that outlive a request but not a deploy, on infrastructure you own: TanStack's detachable runs are the more portable shape, with an experimental label you must price in. Need neither: ignore this axis entirely, it is the one most teams over-buy.

Middleware, telemetry, and the 3 a.m. test

When an agent misbehaves in production, the SDK you want is the one that shows you the run. AI SDK 7 rebuilt telemetry around a single registration: registerTelemetry(new OpenTelemetry()) at startup instruments every SDK function, emitting traces that follow the latest GenAI semantic conventions, covering each step, tool execution, and usage record. It also emits on a Node.js tracing channel, adds per-step performance statistics (time to first output, tokens per second), and fires consistent lifecycle callbacks. Langfuse, Datadog, Sentry, LangSmith and friends plug into this. It is the most complete observability story I have seen in a TypeScript AI SDK, full stop.

TanStack's telemetry story is younger but pointed the right way: @tanstack/ai peer-depends on @opentelemetry/api and ships an ./middlewares/otel subpath, and its middleware model is broader than Vercel's in one respect. wrapLanguageModel() wraps the model - it sees prompts and completions. TanStack chat middleware hooks the whole run: config, chunks, tool calls, usage, finish. Persistence and memory are themselves middleware (withPersistence, memoryMiddleware), which tells you the middleware is a real extension point and not a garnish. For local debugging, TanStack's in-app devtools panel, showing tool calls and finish reasons on one timeline across server and client, is the tool I would reach for first. Verdict on this axis: production observability goes to Vercel today, and it is not close. Extension-point design goes to TanStack.

Testing, errors, and the small print

Both SDKs let you test without burning tokens, which should be table stakes and is not, across this industry. The AI SDK ships ai/test with MockLanguageModelV3 and simulateReadableStream; I verified both import cleanly from the installed package. TanStack ships @tanstack/ai/testing with fakeText() and a FakeTextAdapter, and its own end-to-end suite runs every adapter against deterministic model fixtures with no live calls. Parity, honestly earned on both sides.

Errors are where senior engineers should linger. The AI SDK exports a designed taxonomy: APICallError, RetryError, InvalidToolInputError, ToolCallRepairError (yes, the SDK can attempt to repair a malformed tool call), InvalidToolApprovalSignatureError, NoObjectGeneratedError, and dozens more. You can catch precisely and retry precisely. TanStack's error surface is smaller and younger - a StandardSchemaValidationError, interrupt-resume validation errors, capability errors - adequate, not yet a taxonomy. One more small-print item in Vercel's favor: AI SDK 7 has first-class timeouts - total, per-step, per-chunk, per-tool - as typed config with a TimeoutError. I found no equivalent single timeout surface in TanStack's 1.0 core exports; its docs lean on chat({ retry }) for rate-limited calls instead. And one in TanStack's favor: it runs on Node 18+. The ai package now requires Node 22 or later, per its own engines field. If you maintain a fleet pinned to older Node, that line in a package.json can decide this whole comparison for you.

The scoreboard

Axis Vercel AI SDK 7 TanStack AI 1.0
Current version (Nov 2, 2026) ai 7.0.159 @tanstack/ai 1.0.1
Wire protocol Own UI Message Stream AG-UI (open, bidirectional)
Type safety Per provider; typed tools and message parts Per model; typed options and client messages
Tool definition tool() on the server; client tools via transport One toolDefinition(), .server() or .client()
Agent loop stopWhen conditions; ToolLoopAgent class agentLoopStrategy functions; maxIterations()
Approvals needsApproval, policy functions, HMAC-signed approvals needsApproval, batched approvals, interrupts
Structured output Output.object(), generateObject() - a result chat({ outputSchema }) - a streamed message part
Durable runs WorkflowAgent (GA, Workflow SDK) Detachable runs; harness sessions (experimental 0.x)
Middleware wrapLanguageModel() around the model Named hooks across the whole run
Telemetry registerTelemetry, OTel GenAI conventions, tracing channel OTel middleware subpath; in-app devtools panel
Testing MockLanguageModelV3 in ai/test fakeText() in @tanstack/ai/testing
Frameworks React, Vue, Svelte, Angular React, Vue, Solid, Svelte, Preact, Angular, Octane, Remix, vanilla, React Native
Providers ~38 first-party packages; Gateway built into core 23 adapters plus any OpenAI-compatible endpoint
Node requirement 22+ 18+
License Apache 2.0 MIT

Migration cost, in both directions

Moving from the AI SDK to TanStack is two migrations wearing a trench coat. The server calls are the cheap one: the mapping table above is real, and a route handler converts in under an hour. The protocol is the expensive one: every component that reads UI Message Stream parts, every AI Elements widget, your approval UI, your stream resumption logic, and your stored message format all change dialect at once. TanStack also imposes a discipline the AI SDK does not: threadId is required on client and server in 1.0, and neither side invents one for you. That is correct design and still a migration task. Call the whole move days for a real chat product, and do it for the protocol or the typing, not for fashion.

Moving the other way, from TanStack to the AI SDK, has the mirror-image cost, plus one recurring tax worth naming: cadence. The AI SDK shipped v5 in 2025, v6 on December 22, 2025, and v7 on June 25, 2026 - a major roughly every six months, each with a codemod (npx @ai-sdk/codemod v7 this round). The codemods are good and the migration guides are honest, but a major a half-year is a standing maintenance budget you should enter with open eyes. TanStack's 1.0 is explicitly a stability commitment - their words are "our formal commitment to the APIs you build on" - from a team of three maintainers, with 143 contributors. Believe the commitment; price the team size. Bus factor is an architectural property too.

Where each one breaks

The AI SDK breaks at the platform seam. The Gateway inside the core package, string model ids that route through it, the Workflow SDK under durable agents, the sandbox story centered on Vercel Sandbox: each default is reasonable, and together they mean the path of least resistance ends on Vercel's platform. You can decline every one of those defaults. Most teams, under deadline, will not. It also breaks at upgrade time, when the six-month major cadence meets a codebase with a hundred streamText call sites.

TanStack breaks at the ecosystem seam. Three maintainers. A harness that is honest about being experimental. Fewer production war stories, fewer answered Stack Overflow equivalents, fewer hires who have run it before. Its devtools and docs are excellent, but when your AG-UI stream does something strange at scale, the crowd you can ask is smaller. And its very flexibility - bring your own persistence, your own store, your own sandbox provider - means the integration work Vercel does for you lands on your plate instead.

My verdict: what I would pick, and why

Default pick: the Vercel AI SDK 7, for a Next.js product that needs to be in production this quarter and stay observable, testable, and debuggable when it gets there. Maturity is a feature. Sixteen million weekly downloads is a lot of other people's bug reports finding your bugs before you do, and the telemetry, timeout, and approval-hardening work in v7 is aimed exactly at the failures I have actually had in production AI features.

Pick TanStack AI instead when any of these is true for you:

  • Your frontend is not React-only, or might not stay that way. Nine framework bindings and an open protocol mean the AI layer survives a frontend rewrite.
  • You refuse platform gravity on principle or on contract. There is no gateway in the core, no platform layer at all, and the protocol is a public spec.
  • Your tools live on both client and server, and you want one definition for them.
  • Model-option type errors have burned you, and per-model typing is worth switching for.
  • You are pinned to Node 18 or 20.

And the flip conditions for my default: the day TanStack's harness hits a stable 1.0 with its recovery limits closed, the durability axis stops pointing at Vercel, and this comparison gets much harder. The day your app needs a non-React client speaking to the same agent backend, it flips immediately.

Whichever you pick, wrap it. Put your own thin interface between your product code and the SDK's call sites - one module that owns chat, tools, and model selection. I made that case in full when I built an agent harness in 200 lines of plain TypeScript: the loop is small, and owning the seam means an SDK migration, in either direction, is a week of work instead of a rewrite. If you are scoping an AI feature build and want a second pair of eyes on the architecture before you commit to either SDK, that is the kind of work I take on - or just say hello.

FAQ

Is TanStack AI production-ready at 1.0?

The core is. TanStack shipped 1.0 on October 23, 2026 with a formal stability commitment: core APIs are stable, deprecated 0.x APIs were removed, and upgrades from late 0.x are mostly a codemod plus a type check. The agent harness is the exception - it ships as 0.x, is explicitly experimental, and can change in a minor release. Build on chat(), tools, and middleware today; treat the harness as a beta you pin carefully.

Can I use TanStack AI with Next.js, or does it need TanStack Start?

Next.js works fine. The docs list App Router API routes as a supported host, alongside TanStack Start, React Router v7, Express, Remix 3, and React Native. The server half is just a route handler that returns a streaming Response, and the client half is useChat from @tanstack/ai-react. Nothing in the 1.0 core requires TanStack Start.

What is AG-UI, and why does the wire protocol matter?

AG-UI is an open protocol for agent-to-UI communication: typed events for text, tool calls, state, and run lifecycle, flowing in both directions. TanStack AI speaks it natively - the @ag-ui/core package is a direct dependency of @tanstack/ai. The Vercel AI SDK speaks its own UI Message Stream protocol. The protocol decides which clients, bridges, and third-party agent UIs can talk to your backend without a translation layer, and it is the most expensive part of either SDK to replace later.

Which SDK has better type safety?

TanStack AI goes one level deeper. The AI SDK gives you typed tool inputs, typed UI message parts, and provider packages with their own option types, which is already strong. TanStack types the model options per model: pick a model and TypeScript narrows the options and content types to what that specific model supports, so an unsupported option is a compile error instead of a runtime surprise. On ordinary tool and message typing, the two are comparable.

How hard is it to migrate from the Vercel AI SDK to TanStack AI?

The call sites map almost one to one: streamText becomes chat(), generateObject becomes chat({ outputSchema }), stopWhen: stepCountIs(n) becomes agentLoopStrategy: maxIterations(n). The expensive part is the wire: your client stops speaking the UI Message Stream protocol and starts speaking AG-UI, so the chat UI, any AI Elements components, and anything that consumes the stream gets rewritten. Budget days for the protocol swap, hours for the server calls.

Which one should I pick for a durable, long-running agent?

Today, the Vercel AI SDK, if you accept its terms. AI SDK 7's WorkflowAgent persists execution state between steps, so runs survive deploys, restarts, and delayed approvals - but durability runs on the Workflow SDK, which is Vercel's execution model. TanStack's answer is a detachable run model (detach, journal, takeover) that works on any sandbox provider, plus a harness with durable sessions that is still experimental at 0.x and has documented recovery limits. If the run must survive a restart in production this quarter, WorkflowAgent is the proven path and portability is the price.

Top comments (0)