TL;DR
Four mature, production-ready TypeScript frameworks have made building agents genuinely enjoyable. Here is how to pick the right one - and how they fit together.
Direct answer
Four mature, production-ready TypeScript frameworks have made building agents genuinely enjoyable. Here is how to pick the right one - and how they fit together.
Best for
Developers comparing real tool tradeoffs before choosing a stack.
Covers
Verdict, tradeoffs, pricing signals, workflow fit, and related alternatives.
Read next
The 2026 agent decision is not CrewAI vs LangGraph. It is whether your loop lives in vendor infrastructure, a self-hosted graph runtime, or a plain while-loop you wrote yourself. Here is how to choose.
9 min readApache Burr hit the front page of Hacker News with 142 points today. Here is what it actually does, how it compares to LangGraph and CrewAI, and when you should skip frameworks entirely.
9 min readBoth Mastra and LangGraph.js are serious TypeScript agent frameworks - but they start from opposite philosophies. Here is what that means for your next project.
8 min readTypeScript developers building agents today face an enviable problem: too many excellent options. (For the cross-language view, our agent frameworks comparison covers the Python side.) A year ago the honest advice was "wrap fetch calls in a loop and manage state yourself." Today four mature frameworks compete for the same problem space, each with distinct opinions, genuine production deployments, and active doc sites that answer questions faster than a Stack Overflow thread ever did.
This is a good problem to have. The TypeScript AI ecosystem has quietly caught up with its Python counterpart, and in some areas - React streaming integration, edge deployment, TypeScript-first ergonomics - it has pulled ahead. Whether you are adding an AI feature to a Next.js app or building a standalone multi-agent service, there is a framework that fits your exact situation.
Last updated: June 10, 2026
Before diving into each framework individually, it helps to understand the altitude at which they operate. These are not four competing implementations of the same thing. They sit at different layers of the stack and, as we will see at the end, they compose rather than compete.
npm i ai) - low-level primitives: generateText, streamText, useChat. The React streaming story for AI. Agnostic across 100+ models.npm create mastra) - batteries-included TypeScript framework: agents, workflows, memory, evals, MCP, deployment. Built by the Gatsby team.@openai/agents) - handoffs, guardrails, and a typed context object. OpenAI-native but supports custom model implementations.@langchain/langgraph) - explicit state graphs with durable checkpoints. Maximum control over agent topology.The AI SDK is the foundational layer that most of the TypeScript ecosystem already uses, often without labeling it as an "agent framework." Its core exports are two functions: generateText for request-response generation, and streamText for token streaming. Both accept a model-agnostic model parameter - swap a string and you swap providers.
import { generateText } from 'ai';
const { text } = await generateText({
model: 'anthropic/claude-sonnet-4.5',
prompt: 'What is love?',
});
The agent story in v6 centers on loop control inside generateText and streamText. The loop continues until one of four conditions is met: the model stops calling tools, a tool has no execute function, a tool call needs human approval, or a stop condition fires. You control that last case with stopWhen:
import { generateText, stepCountIs, isLoopFinished } from 'ai';
const { text } = await generateText({
model: 'openai/gpt-5.4',
tools: { searchWeb, writeFile },
stopWhen: stepCountIs(50), // override the default of 20
});
The built-in stop condition helpers are stepCountIs(n), hasToolCall(toolName), and isLoopFinished() (no step limit). The prepareStep callback lets you swap model, tools, or messages between steps - useful for cost optimization where early reasoning uses a larger model and later steps use a smaller one.
The second pillar is AI SDK UI: React hooks (useChat, useCompletion) that wire streaming responses directly into your component tree. This is the most seamless path to production in a Next.js app. The useChat hook handles message persistence, stream resumption, and generative UI patterns (rendering React components from streamed JSON) out of the box.
Sweet spot: Adding AI features to an existing Next.js or React app; building model-agnostic utility functions that other code consumes; or serving as the low-level inference layer inside a higher-level framework.
Mastra is what happens when a team that shipped Gatsby decides to build a full-featured agent framework. It is built by the Gatsby founders, ships as an open-source Apache 2.0 package, and is already deployed by companies including Replit, Sanity, and WorkOS.
The Agent class is clean and readable:
import { Agent } from '@mastra/core/agent';
const chefAgent = new Agent({
id: 'chef-agent',
name: 'Chef Michel',
instructions: 'You are Michel, a practical home chef.',
model: 'openai/gpt-5-mini', // "provider/model-name" format
tools: { fetchIngredients, printRecipe },
});
Models are specified as "provider/model-name" strings through Mastra's own model router, which covers 4,000+ models from 124 providers - completely independent of the Vercel AI SDK. You register agents in a central Mastra instance that wires up shared memory, logging, and observability:
import { Mastra } from '@mastra/core';
export const mastra = new Mastra({
agents: { chefAgent },
});
// Then call it anywhere
const agent = mastra.getAgentById('chef-agent');
const response = await agent.generate('Help me organize my day');
// or stream:
const stream = await agent.stream('What can I cook with eggs and flour?');
for await (const chunk of stream.textStream) {
process.stdout.write(chunk);
}
The feature that separates Mastra from "just an agent wrapper" is its workflow engine. Workflows use .then(), .branch(), and .parallel() to describe deterministic multi-step processes with explicit control flow. They support human-in-the-loop suspension: a workflow can pause indefinitely, serialize its state to storage, and resume where it left off when a human approves the next step. This makes Mastra practical for business processes (content approval, customer onboarding, compliance reviews) where you cannot run a continuous process.
Beyond agents and workflows, Mastra ships built-in evals (model-graded, rule-based, and statistical scorers), guardrails for input/output sanitization, MCP server authoring, conversation memory, RAG tooling, a local dev Studio for visualizing agent runs, and deployers for Vercel, Netlify, and Cloudflare. It integrates as a route handler in Next.js or Hono, or ships as a standalone server.
The honest note: Mastra has its own model routing layer, not the Vercel AI SDK. The two are parallel choices at the model-communication level, and Mastra's abstraction is deliberately self-contained.
Sweet spot: Standalone agent services; anything that needs workflows with suspend/resume; projects where you want a single framework covering agents, memory, evals, and deployment without assembling the pieces yourself.
Get the weekly deep dive
Tutorials on Claude Code, AI agents, and dev tools - delivered free every week.
From the archive
Jun 10, 2026 • 7 min read
Jun 8, 2026 • 8 min read
Jun 7, 2026 • 5 min read
Jun 7, 2026 • 8 min read
@openai/agents)The OpenAI Agents SDK is the TypeScript port of the Python Agents SDK and brings the same two killer features: handoffs and guardrails. If you were at all impressed by the Python version, the TS version is ready and the API is nearly identical.
An Agent is defined with instructions, an optional model, and tools. The runner executes the agent loop:
import { Agent, tool, run } from '@openai/agents';
import { z } from 'zod';
const getWeather = tool({
name: 'get_weather',
description: 'Return the weather for a given city.',
parameters: z.object({ city: z.string() }),
async execute({ city }) {
return `The weather in ${city} is sunny.`;
},
});
const agent = new Agent({
name: 'Weather bot',
instructions: 'You are a helpful weather bot.',
model: 'gpt-4.1',
tools: [getWeather],
});
const result = await run(agent, 'What is the weather in Tokyo?');
Handoffs let a triage agent hand off the entire conversation to a specialist. The SDK handles context passing automatically:
const bookingAgent = new Agent({ name: 'Booking expert', instructions: '...' });
const refundAgent = new Agent({ name: 'Refund expert', instructions: '...' });
const frontlineAgent = new Agent({
name: 'Customer-facing agent',
instructions: 'Route booking questions to booking_expert, refunds to refund_expert.',
tools: [
bookingAgent.asTool({ toolName: 'booking_expert', toolDescription: '...' }),
refundAgent.asTool({ toolName: 'refund_expert', toolDescription: '...' }),
],
});
The inputGuardrails and outputGuardrails properties accept guardrail functions that run in parallel with the model call and can trip a GuardrailTripwireTriggered exception - a clean pattern for content safety without adding latency to the happy path.
Agents are generic on a typed context: Agent<TContext, TOutput>. The context is dependency injection - you create it and pass it to run(), and every tool and guardrail receives it. This is genuinely useful for per-request state like user authentication, feature flags, or a database connection.
The SDK is OpenAI-native (it uses the Responses API by default and OpenAI structured outputs for typed outputType), but it does expose a Model interface for custom implementations - so other providers are possible with additional wiring.
Sweet spot: Multi-agent systems where clean handoff semantics matter; OpenAI-centric production deployments; teams that want strong typing on the context passed through an agent chain.
LangGraph.js is for developers who want to see exactly what their agent is doing at every step. Where the other frameworks hide the loop, LangGraph makes you draw it. You define a StateGraph, add nodes, add edges, and compile. The result is a named, inspectable, resumable execution graph.
import {
StateGraph, StateSchema, MessagesValue,
ReducedValue, START, END,
} from '@langchain/langgraph';
import { z } from 'zod/v4';
const MessagesState = new StateSchema({
messages: MessagesValue,
llmCalls: new ReducedValue(
z.number().default(0),
{ reducer: (x, y) => x + y }
),
});
const agent = new StateGraph(MessagesState)
.addNode('llmCall', llmCall)
.addNode('toolNode', toolNode)
.addEdge(START, 'llmCall')
.addConditionalEdges('llmCall', shouldContinue, ['toolNode', END])
.addEdge('toolNode', 'llmCall')
.compile();
const result = await agent.invoke({
messages: [new HumanMessage('Add 3 and 4.')],
});
The MessagesValue is a built-in reducer that appends messages - you get append semantics for free. Custom state fields use ReducedValue with explicit reducer functions. This explicit state management is the core feature: you always know what is in the state, how it got there, and what the next node will see.
LangGraph's checkpoint system is where it pulls ahead for long-running or fault-tolerant work. Checkpoints serialize state after every node execution. A graph that processes a 10-step approval workflow can crash on step 7, resume from step 7 on the next request, and the caller never knows anything went wrong. The cloud-hosted LangGraph Platform (separate product) adds a visual debugger, trace viewer, and managed deployment.
The tradeoff is verbosity. A simple react loop takes 30-40 lines in LangGraph versus 5 in the AI SDK. That verbosity is exactly the point for teams that need auditability, but it is overhead you pay on every graph.
Sweet spot: Enterprise workflows where every state transition needs to be logged and auditable; long-running agents that must survive infrastructure failures; teams already invested in the LangChain ecosystem; research work where iterating on graph topology is part of the process.
The more you work with these tools, the more you notice they are designed to be used together:
useChat for streaming UI, the backend is a Mastra server handling workflows and memory. The AI SDK never needs to know Mastra exists..then()/.branch() syntax, then port the topology to a LangGraph StateGraph when you need fine-grained checkpoint control.None of these frameworks lock you into their full stack. The AI SDK is already the standard inference layer for the JS ecosystem - 14 million weekly downloads do not lie.
| Vercel AI SDK v6 | Mastra | OpenAI Agents SDK | LangGraph.js | |
|---|---|---|---|---|
| Abstraction level | Primitives / hooks | Full framework | Agent + orchestration | Graph runtime |
| Model support | 100+ via providers | 4,000+ via own router | OpenAI-native, custom Model interface | Provider-agnostic (LangChain models) |
| State / memory | Bring your own | Built-in memory + storage | Typed context object | Explicit StateSchema + reducers |
| Multi-agent | Subagents via tools | Supervisor agents, agent-as-tool | Handoffs + manager pattern | Graph nodes as agents |
| React / UI story | Best-in-class (useChat, generative UI) | Integrates with Next.js via server adapters | None built-in | None built-in |
| Deployment | Vercel native; edge-ready | Vercel, Netlify, Cloudflare, standalone Hono | Self-managed or any Node runtime | LangGraph Platform or self-managed |
| Best for | Next.js features, streaming UI, model-agnostic utilities | Standalone agent services, batteries-included apps | Handoff-heavy multi-agent, OpenAI-centric production | Durable workflows, enterprise auditability, graph-topology research |
Building a Next.js app feature (chatbot, copilot sidebar, inline assistant): Start with the Vercel AI SDK. useChat + a route handler is 20 lines of code and works on the edge. Add Mastra as a separate service if the backend logic grows into workflows or multi-step memory.
Building a standalone agent service (API endpoint, background worker, CLI tool): Mastra is the natural fit. You get the local dev Studio, evals, MCP support, and deployers without assembling them from parts. The workflow engine covers the cases where you need deterministic multi-step execution alongside open-ended agent calls.
Building a multi-agent system (triage + specialist routing, customer support with departments): OpenAI Agents SDK if you are OpenAI-centric and want clean handoff semantics. Mastra supervisor agents if you need provider flexibility and a full framework around it.
Building an enterprise workflow (audit trail required, human approval gates, long-running processes that must survive failures): LangGraph.js. The explicit graph + checkpointing combination is the right architecture here, and the LangGraph Platform adds the observability tooling that enterprise deployments need.
Yes. Mastra is used in production by Replit, Sanity, WorkOS, SoftBank-backed teams, and others. The core framework is Apache 2.0 open-source with a separate enterprise license for advanced features. It ships a 1.0 stable API and the team has invested heavily in the local dev Studio and eval tooling that indicate production readiness.
Different tools for different layers. The Vercel AI SDK is model-agnostic inference primitives plus React streaming hooks - it does not have opinions about agent topology or multi-agent orchestration. The OpenAI Agents SDK is specifically about structuring agent-to-agent relationships (handoffs, guardrails, typed context), and it is opinionated about OpenAI as the primary provider. Many production systems use both: AI SDK for the inference calls and streaming, OpenAI Agents SDK for the orchestration layer when deploying to OpenAI's platform.
LangGraph.js uses LangChain model abstractions (like ChatAnthropic) in its examples, but the graph engine itself (StateGraph, nodes, edges, checkpoints) does not require LangChain models. You can use any model that returns message-shaped objects. That said, if you are not already in the LangChain ecosystem, the startup cost is real - you are learning both the graph model and the LangChain message types simultaneously.
Yes. Mastra's model router supports 124 providers including Anthropic, Google, Mistral, and more. You specify models as "provider/model-name" strings (e.g., "anthropic/claude-sonnet-4-5") and Mastra reads the corresponding API key from your environment. Provider lock-in is explicitly something Mastra is designed to prevent.
maxSteps in Vercel AI SDK?The v4 maxSteps parameter has been replaced in v6 with stopWhen, which accepts stop condition helpers: stepCountIs(n), hasToolCall(toolName), and isLoopFinished(). The default is stepCountIs(20) - a safety limit on runaway loops. Use stopWhen: isLoopFinished() to let the agent run until the model naturally stops calling tools, or stopWhen: stepCountIs(50) to raise the limit.
Documentation scraped and verified June 10, 2026:
generateText, streamText, stopWhen, stepCountIs, isLoopFinished)tool(), run(), handoffs via .asTool(), inputGuardrails, outputGuardrails, typed context)StateGraph, StateSchema, MessagesValue, ReducedValue, addConditionalEdges, compile)Technical content at the intersection of AI and development. Building with AI agents, Claude Code, and modern dev tools - then showing you exactly how it works.
The TypeScript toolkit for building AI apps. Unified API across OpenAI, Anthropic, Google. Streaming, tool calling, stru...
View ToolTypeScript-first AI agent framework. Agents, tools, memory, workflows, RAG, evals, tracing, MCP, and production deployme...
View ToolFrontend stack for agent-native apps. React hooks, prebuilt copilot UI, AG-UI runtime, frontend tools, shared state, and...
View ToolOpenAI's coding agent for terminal, cloud, IDE, GitHub, Slack, and Linear workflows. Reads repos, edits files, runs comm...
View ToolDeep comparison of the top AI agent frameworks - LangGraph, CrewAI, Mastra, CopilotKit, AutoGen, and Claude Code.
AI AgentsStep-by-step guide to building an MCP server in TypeScript - from project setup to tool definitions, resource handling, testing, and deployment.
AI AgentsConfigure Claude Code for maximum productivity -- CLAUDE.md, sub-agents, MCP servers, and autonomous workflows.
AI Agents
Auto Agent: Self-Improving AI Harnesses Inspired by Karpathy’s Auto-Research Loop The video explains self-improving agents and highlights Kevin Guo’s Auto Agent project as an extension of Andrej Karp...

Check out Replit: https://replit.com/refer/DevelopersDiges The video demos Replit’s Agent 4, explaining how Replit evolved from a cloud IDE into a platform where users can build, deploy, and scale ap...
The 2026 agent decision is not CrewAI vs LangGraph. It is whether your loop lives in vendor infrastructure, a self-hoste...
Apache Burr hit the front page of Hacker News with 142 points today. Here is what it actually does, how it compares to L...
Both Mastra and LangGraph.js are serious TypeScript agent frameworks - but they start from opposite philosophies. Here i...

A practical field note on where Mastra, CopilotKit, and LangGraph fit when you are building the same agent-native produc...

CopilotKit is strongest when you treat it as the product-facing agent UI layer: chat surfaces, frontend tools, shared st...
A hands-on look at Mastra, the open source TypeScript framework for building production-ready AI agents and workflows --...

New tutorials, open-source projects, and deep dives on coding agents - delivered weekly.