Vercel AI SDK is a streaming UI library, not an agent framework — it has no durable workflows, no first-class memory, and no orchestration primitives beyond a tool loop. LangGraph TypeScript exists but trails the Python edition by 4-8 weeks per release and inherits Python idioms that feel wrong in a Next.js codebase. Mastra is the TS-native answer: durable workflows on Inngest or its own runtime, pluggable memory (Postgres, Upstash, LibSQL), evals as first-class primitives, and AI SDK streaming reused at the UI edge. Pick Vercel AI SDK for chat UIs without orchestration. Pick LangGraph TS only if your team is bilingual with a Python service of record. Pick Mastra for everything else — agents, durable workflows, multi-step pipelines — in a TypeScript codebase.
We took on a TypeScript agent project in March that was already half-built in LangGraph TS. Six tools, a branching workflow, Postgres-backed memory, three weeks of work behind it. The handoff was painful: the original engineer had been fighting type assertions, the TS port was missing two features that had landed in Python LangGraph the week before, and the checkpointer was crashing when a tool call returned more than 2 KB of output. Total time burned to date: 41 engineering hours, no production traffic yet.
We rebuilt the same thing in Mastra in 18 hours. Six tools, same branching workflow, same Postgres memory, durable workflow on Inngest, streaming through Vercel AI SDK at the React edge. It went into production three days later.
That ratio — 41 to 18 hours for the same agent — is why the TypeScript agent framework conversation has shifted in 2026. Not because Mastra is magic, but because LangGraph and Vercel AI SDK each picked one half of the problem and Mastra is the first credible attempt to ship both halves in idiomatic TS. This post is the head-to-head, with the trade-offs we have actually hit on client work. For the broader agent-framework landscape including Python options, see our LangGraph vs CrewAI vs OpenAI Agents SDK comparison and our Microsoft Agent Framework vs Google ADK vs smolagents post.
The TypeScript Agent Framework Gap, in One Picture
The gap that Mastra fills is easier to see if you list what each framework is actually trying to be.
If you only need a chat UI with a single tool loop, Vercel AI SDK is the best tool in the world for that job and you should not reach further. The trouble is that "single tool loop" is rare in production. Real agents need to remember what happened yesterday, survive a deploy mid-execution, fan out to parallel sub-tasks, and have an eval harness that catches regressions before they ship. None of those are in the Vercel AI SDK box.
LangGraph has all of those — in Python. The TypeScript port is real and shipping, but it is downstream. Every time the Python team adds interrupt semantics or a new checkpointer, the TS team ports it later. We measured the lag at 4 to 8 weeks per minor release in 2025 and it has not closed in 2026. For a Next.js team that wants the latest features the day they ship, that lag is a daily papercut.
Mastra is the team that decided "build the LangGraph equivalent, but TS-first, and ship it on top of the rest of the modern TS stack." Inngest for durable workflows. Drizzle, Postgres, Upstash, or LibSQL for memory. Vercel AI SDK for the React streaming edge. AI SDK 4.x types reused throughout. The result reads like a TS framework written by people who actually use TS.
| Framework | What it actually is | What it is missing |
|---|---|---|
| Vercel AI SDK | A streaming UI library + thin tool loop for React/Next.js | Durable workflows, persistent memory, eval harnesses, multi-agent orchestration |
| LangGraph TS | A Python-first graph orchestration framework with a TS port | Idiomatic TS ergonomics, parity with Python release cadence, lightweight runtime |
| Mastra | A TS-native agent framework: agents + workflows + memory + evals + tools | Maturity (it is 18 months old), the depth of the LangChain ecosystem |
Mastra: The TS-Native Answer
A minimal Mastra agent looks like this:
import { Agent } from "@mastra/core/agent";
import { openai } from "@ai-sdk/openai";
import { Memory } from "@mastra/memory";
import { stripeRefundTool, lookupOrderTool } from "./tools";
export const refundAgent = new Agent({
name: "refund_resolver",
instructions: `You resolve refund requests. Verify policy, check
eligibility, and either issue the refund or hand off to a human
reviewer above $250.`,
model: openai("gpt-5"),
tools: { stripeRefundTool, lookupOrderTool },
memory: new Memory({ storage: { type: "postgres" } }),
});That is the whole agent. The same primitives — Agent, Memory, tool definitions — feel like the AI SDK with a lot more behind them. Memory is real (it persists across requests, supports working memory and long-term memory, and can be backed by Postgres, Upstash, LibSQL, or Pinecone). Tools are typed end-to-end. There is no class-based mutable state object you have to thread through a graph.
Where it pulls ahead of Vercel AI SDK is the workflow primitive. Workflows are durable, branching, parallel, and replayable:
import { Workflow, Step } from "@mastra/core/workflow";
export const onboardingWorkflow = new Workflow({
name: "onboarding",
triggerSchema: z.object({ accountId: z.string() }),
})
.step(new Step({ id: "verify", execute: verifyAccount }))
.step(new Step({ id: "enrich", execute: enrichWithCRM }))
.parallel([
new Step({ id: "send_welcome", execute: sendWelcomeEmail }),
new Step({ id: "schedule_call", execute: scheduleKickoff }),
])
.commit();Wire that workflow into Inngest and every step gets a durable journal entry. Crash mid-execution and the next replay picks up where it left off. We covered the broader durable execution pattern in our post on agent loops and reasoning step optimization — Mastra workflows are the cleanest implementation of that pattern in TS we have seen.
The other thing Mastra ships that Vercel AI SDK does not is evals as a first-class primitive. You can attach an eval scorer to an agent or a workflow, run it against a golden set, and gate deploys on the result:
import { evaluate } from "@mastra/evals";
await evaluate(refundAgent, {
testCases: refundGoldenSet,
scorers: [policyComplianceScorer, costScorer],
threshold: 0.9,
});That is the same shape we have been advocating in our evals-driven development workflow post, and it is built into the framework rather than bolted on.
LangGraph TypeScript: Feature Parity vs Python Lag
LangGraph TS is real and used in production by serious teams. It is not vaporware. The honest critique is that the developer experience trails the Python edition in three concrete ways.
Release cadence lag. When LangGraph Python ships a feature — durable execution, the new interrupt API, the Send primitive for fan-out — the TS port follows somewhere between 4 and 8 weeks later. We have hit this on three client projects in the last six months. If your team is bilingual and your service of record is Python with a TS frontend agent, this is fine. If you are TS-only, you are perpetually behind.
Idiom mismatch. A LangGraph TS agent reads like Python translated:
const graph = new StateGraph(AgentState)
.addNode("agent", callAgent)
.addNode("tools", toolNode)
.addConditionalEdges("agent", shouldContinue)
.addEdge("tools", "agent")
.compile();That works, but the mutable AgentState object, the conditional-edge function returning string node names, and the compile() step on the builder all feel imported from another language. Compare to Mastra's Workflow.step().parallel().commit() chain, which composes like the rest of a modern TS codebase. Neither is wrong; one is more at home in Next.js.
Ecosystem assumptions. LangGraph assumes you have Postgres for the checkpointer and that you are happy on LangSmith for traces. Many TS teams run on Vercel + Cloudflare + a serverless Postgres like Neon or PlanetScale, and they are running Langfuse, Helicone, or homegrown OpenTelemetry for observability. LangGraph runs there, but you fight the defaults.
The case for LangGraph TS in 2026: your team has heavy Python investment, a Python service of record, and you want to share orchestration patterns across the language boundary. The case against: anything else.
Vercel AI SDK: Stop Calling It an Agent Framework
The most consequential thing we can say about Vercel AI SDK is that it is not an agent framework. It is a streaming UI library plus a thin tool loop. That is not a criticism; it is a deliberate scope decision by the Vercel team and it is the right call for the use case the SDK was built for.
import { generateText } from "ai";
import { openai } from "@ai-sdk/openai";
const result = await generateText({
model: openai("gpt-5"),
tools: { weather: weatherTool, calendar: calendarTool },
maxSteps: 5,
messages: [{ role: "user", content: "Plan my trip." }],
});That is the whole loop. It will run up to five tool steps, stream tokens to the React client, and exit. There is no checkpointing. There is no persistent memory across sessions. There is no parallel sub-agent fan-out. There is no eval harness. If the process restarts mid-execution, the conversation is gone.
For a chat UI with no multi-step orchestration, that simplicity is exactly what you want. We ship Vercel AI SDK every week for this shape of work — internal tools, customer support assistants, doc-search interfaces. The mistake we see teams make is reaching for it when they actually need workflows, memory, and evals, then bolting on a checkpointer, a memory store, and a Zustand-like state machine until they have rebuilt half of Mastra.
The clean answer: ship Vercel AI SDK at the streaming edge in React, and let Mastra (or LangGraph TS) own the agent runtime on the server. Mastra agents already return AI SDK-compatible streams, so the useChat hook works without translation.
The Decision Matrix We Actually Use
We pick by mapping the project to four axes: orchestration depth, memory permanence, streaming UI requirement, and eval maturity.
The pattern that falls out: Vercel AI SDK alone for chat UIs, Mastra for everything that needs durability or memory, LangGraph TS only when you have a Python service of record on the other side of the wire.
| Need | Vercel AI SDK alone | LangGraph TS | Mastra |
|---|---|---|---|
| Single tool loop, chat UI | ✅ Best fit | Overkill | Overkill |
| Multi-step workflow, ephemeral state | ⚠️ Hand-rolled state machine | ✅ Works | ✅ Works |
| Durable workflow (survives restart) | ❌ Not supported | ✅ Postgres checkpointer | ✅ Inngest or self-hosted |
| Persistent agent memory across sessions | ❌ Not supported | ✅ Via checkpointer threads | ✅ First-class memory module |
| Parallel sub-agent fan-out | ❌ Not supported | ✅ Send primitive | ✅ Workflow.parallel() |
| Eval harness against golden set | ❌ Bring your own | ⚠️ LangSmith-coupled | ✅ Built-in evaluate() |
| React streaming + optimistic UI | ✅ Best fit | ⚠️ AI SDK adapter required | ✅ Native AI SDK streams |
| Bilingual TS + Python team | ⚠️ TS only | ✅ Feature parity with Python | ⚠️ TS only |
Migration Story: 41 to 18 Hours
The numbers from the migration we mentioned in the intro break down as follows.
LangGraph TS, original build (41 hours):
Mastra rebuild (18 hours):
step().parallel() chain + Inngest setupThe Mastra build was not faster because Mastra is doing less. It was faster because the framework's defaults match how a modern TS codebase is structured. We did not write a single class. We did not thread mutable state through a graph. We did not have to wait for a feature.
For a deeper read on why durable execution and memory are the load-bearing primitives in agent frameworks — and why Vercel AI SDK does not ship them — see our piece on AI agent memory and context management.
When to Drop the Framework Entirely
Three out of every ten "agent" projects we see in TypeScript codebases should not be agents at all. They are deterministic workflows with one or two LLM calls dropped in for classification or summarization. The LLM is not autonomously choosing tools; it is a function call inside a state machine. Reaching for any of these frameworks for that shape of work is a tax you pay forever.
The test we use: draw the state diagram on a whiteboard. If it has fewer than ten states, all transitions are deterministic, and the LLM call(s) are scoped to specific states, write a state machine — XState, your own reducer, even a switch statement. Use Vercel AI SDK at the LLM call sites. Skip the agent framework entirely.
Pull in Mastra when the state space is large, branching, or non-deterministic enough that the framework's checkpointing earns its keep. Pull in LangGraph TS when you are bilingual with Python on the other side. Pull in Vercel AI SDK alone when it is a chat UI.
Most TypeScript teams will land on Mastra in 2026, and the migration cost from a half-built LangGraph or AI-SDK-plus-glue codebase is lower than people expect. If you are in that spot — handed an agent in TS that is fighting its own framework — we have done this migration enough times now that we are happy to shortcut the path. Particula Tech ships production AI agents on whichever framework matches the workload, and we will tell you when the right answer is "drop the framework and write a state machine." For more on the broader landscape, see our pillar on AI agents.
Frequently Asked Questions
Quick answers to common questions about this topic
Mastra is a TypeScript-native agent framework built by the Gatsby founders. Where Vercel AI SDK is a streaming UI library wrapped around model calls and LangGraph is a Python-first graph orchestration framework with a TypeScript port, Mastra ships agents, durable workflows, memory, evals, and tool registries as first-class primitives in TS. It runs on Node.js, Bun, or Cloudflare Workers, integrates with Vercel AI SDK at the streaming layer, and uses Inngest or its own runtime for durable execution. As of May 2026 it has roughly 18K GitHub stars and a contributor base that ships weekly.

