Skip to main content
← All Articles · · 16 min read

Vercel AI SDK vs LangChain.js vs Mastra: AI Framework Comparison 2026

A comprehensive technical comparison of Vercel AI SDK, LangChain.js, and Mastra for building AI applications in 2026 — covering streaming, tool calling, RAG, agents, and when to choose each.

aillmvercel-ai-sdklangchainmastraragagentstypescriptnextjsjavascript

The JavaScript AI framework ecosystem has matured rapidly. In early 2024, LangChain.js was the default choice. By late 2025, Vercel AI SDK had captured most of the Next.js ecosystem, and Mastra emerged as a focused competitor with a compelling DX story. In 2026, all three are production-grade — but they serve different use cases.

This guide gives you code-level comparisons so you can make an informed choice.


Quick Comparison: At a Glance

Vercel AI SDKLangChain.jsMastra
Primary use caseUI streaming in Next.js/ReactComplex multi-step chains/agentsAgent workflows with memory
Learning curveLowHighMedium
Streaming supportFirst-class (useChat, streamText)Yes (via callbacks)Yes (built-in)
Tool callingExcellent (Zod schema)Good (multiple formats)Excellent (typed)
RAG supportBasic (bring your own vector)Full pipelineBuilt-in vector integration
Agent supportVia generateText + toolsFull agent executorFirst-class workflows
Multi-modelYes (60+ providers via AI SDK)Yes (many providers)Yes (provider-agnostic)
MemoryManualVia ConversationBufferMemoryBuilt-in short/long-term
ObservabilityLangSmith, customLangSmith, LangFuseBuilt-in tracing
Bundle sizeSmall (ai core ~35KB)Large (tree-shake needed)Medium
Maintained byVercelLangChain Inc.Mastra Labs

Vercel AI SDK: Streaming-First, React-Native

Vercel AI SDK (ai package) is designed around one core insight: in web apps, streaming UX is the product. Every primitive is built to make streaming to the browser trivially easy.

Setup

npm install ai @ai-sdk/openai
# or
npm install ai @ai-sdk/anthropic @ai-sdk/google

Basic text generation

import { generateText } from 'ai';
import { openai } from '@ai-sdk/openai';

const { text } = await generateText({
  model: openai('gpt-4o'),
  prompt: 'Explain dependency injection in 3 sentences.',
});

Streaming to the UI — the killer feature

// app/api/chat/route.ts (Next.js App Router)
import { streamText } from 'ai';
import { openai } from '@ai-sdk/openai';

export async function POST(req: Request) {
  const { messages } = await req.json();

  const result = streamText({
    model: openai('gpt-4o'),
    messages,
  });

  return result.toDataStreamResponse();
}
// components/Chat.tsx
'use client';
import { useChat } from 'ai/react';

export function Chat() {
  const { messages, input, handleInputChange, handleSubmit } = useChat();

  return (
    <div>
      {messages.map(m => (
        <div key={m.id}>
          <strong>{m.role}:</strong> {m.content}
        </div>
      ))}
      <form onSubmit={handleSubmit}>
        <input value={input} onChange={handleInputChange} />
        <button type="submit">Send</button>
      </form>
    </div>
  );
}

That’s a full streaming chat UI in ~25 lines. No custom WebSocket, no manual chunk parsing, no state management — useChat handles all of it.

Tool calling with Zod

import { generateText, tool } from 'ai';
import { openai } from '@ai-sdk/openai';
import { z } from 'zod';

const { text, toolCalls } = await generateText({
  model: openai('gpt-4o'),
  tools: {
    getWeather: tool({
      description: 'Get the weather for a city',
      parameters: z.object({
        city: z.string().describe('City name'),
        unit: z.enum(['celsius', 'fahrenheit']).default('celsius'),
      }),
      execute: async ({ city, unit }) => {
        // real API call here
        return { temperature: 22, condition: 'sunny', city, unit };
      },
    }),
  },
  prompt: 'What is the weather in Tokyo?',
  maxSteps: 5,  // allow multi-turn tool use
});

Multi-model with minimal change

import { anthropic } from '@ai-sdk/anthropic';
import { google } from '@ai-sdk/google';

// Swap model without changing any other code
const result = await streamText({
  model: anthropic('claude-sonnet-4-6'),  // or google('gemini-2.0-flash')
  messages,
});

When Vercel AI SDK is the right choice

  • You’re building with Next.js or any React framework
  • Streaming UX is a priority (chat, copilots, live generation)
  • You want a small, well-typed API surface
  • You don’t need complex multi-hop chains or persistent memory

LangChain.js: The Swiss Army Knife

LangChain.js is the oldest and most feature-complete framework. Its model is chains — composable units that can be linked, branched, and orchestrated into complex pipelines.

Setup

npm install langchain @langchain/openai @langchain/core

Basic chain

import { ChatOpenAI } from '@langchain/openai';
import { ChatPromptTemplate } from '@langchain/core/prompts';
import { StringOutputParser } from '@langchain/core/output_parsers';

const model = new ChatOpenAI({ model: 'gpt-4o' });
const prompt = ChatPromptTemplate.fromTemplate(
  'Summarize this article in bullet points:\n\n{article}'
);
const parser = new StringOutputParser();

const chain = prompt.pipe(model).pipe(parser);

const result = await chain.invoke({ article: '...' });

RAG pipeline — LangChain’s strength

import { ChatOpenAI } from '@langchain/openai';
import { OpenAIEmbeddings } from '@langchain/openai';
import { MemoryVectorStore } from 'langchain/vectorstores/memory';
import { createStuffDocumentsChain } from 'langchain/chains/combine_documents';
import { createRetrievalChain } from 'langchain/chains/retrieval';
import { ChatPromptTemplate } from '@langchain/core/prompts';
import { Document } from '@langchain/core/documents';

// 1. Embed documents
const embeddings = new OpenAIEmbeddings();
const vectorStore = await MemoryVectorStore.fromDocuments(
  [
    new Document({ pageContent: 'pnpm uses a content-addressable store...' }),
    new Document({ pageContent: 'Yarn Berry introduces Plug\'n\'Play...' }),
  ],
  embeddings
);

// 2. Build retriever
const retriever = vectorStore.asRetriever({ k: 2 });

// 3. Build QA chain
const model = new ChatOpenAI({ model: 'gpt-4o' });
const prompt = ChatPromptTemplate.fromTemplate(`
Answer based on context only:
<context>{context}</context>
Question: {input}
`);

const documentChain = await createStuffDocumentsChain({ llm: model, prompt });
const retrievalChain = await createRetrievalChain({
  retriever,
  combineDocsChain: documentChain,
});

const { answer } = await retrievalChain.invoke({
  input: 'How does pnpm save disk space?',
});

Agent executor

import { createOpenAIFunctionsAgent, AgentExecutor } from 'langchain/agents';
import { ChatOpenAI } from '@langchain/openai';
import { pull } from 'langchain/hub';
import { TavilySearchResults } from '@langchain/community/tools/tavily_search';

const tools = [new TavilySearchResults({ maxResults: 3 })];
const model = new ChatOpenAI({ model: 'gpt-4o' });
const prompt = await pull<ChatPromptTemplate>('hwchase17/openai-functions-agent');

const agent = await createOpenAIFunctionsAgent({ llm: model, tools, prompt });
const executor = new AgentExecutor({ agent, tools });

const result = await executor.invoke({
  input: 'What are the top 3 JavaScript trends in 2026?',
});

Streaming in LangChain

const stream = await chain.stream({ article: '...' });

for await (const chunk of stream) {
  process.stdout.write(chunk);
}

// Or with callbacks
const result = await chain.invoke(
  { article: '...' },
  { callbacks: [{ handleLLMNewToken: (token) => console.log(token) }] }
);

When LangChain.js is the right choice

  • You need a battle-tested RAG pipeline with vector store integrations
  • You’re building complex multi-step chains with branches/conditionals
  • You need access to LangChain’s large ecosystem of integrations (100+ vector stores, loaders, tools)
  • You’re already using LangSmith for evaluation and observability
  • You need cross-language parity with LangChain Python

Mastra: The Agent-First Framework

Mastra is the newest of the three, purpose-built for agent workflows with built-in memory, deterministic state machines, and first-class observability.

Setup

npm install @mastra/core

Basic agent

import { Mastra } from '@mastra/core';
import { Agent } from '@mastra/core/agent';
import { openai } from '@ai-sdk/openai';  // Mastra uses AI SDK models

const mastra = new Mastra();

const researchAgent = new Agent({
  name: 'ResearchAgent',
  instructions: 'You are a technical research assistant.',
  model: openai('gpt-4o'),
});

const { text } = await researchAgent.generate(
  'Summarize the key differences between REST and GraphQL.'
);

Tool calling

import { createTool } from '@mastra/core/tools';
import { z } from 'zod';

const searchTool = createTool({
  id: 'web-search',
  description: 'Search the web for information',
  inputSchema: z.object({ query: z.string() }),
  outputSchema: z.object({
    results: z.array(z.object({ title: z.string(), url: z.string() })),
  }),
  execute: async ({ context: { query } }) => {
    // real search implementation
    return { results: [{ title: 'Result 1', url: 'https://...' }] };
  },
});

const agent = new Agent({
  name: 'SearchAgent',
  instructions: 'Use search to answer questions.',
  model: openai('gpt-4o'),
  tools: { searchTool },
});

Workflows — Mastra’s unique feature

Mastra’s Workflow API is a deterministic state machine for multi-step agent pipelines. Unlike LangChain chains (which are functional compositions), Mastra workflows are explicit DAGs with error handling and retry built in:

import { Workflow, Step } from '@mastra/core/workflows';
import { z } from 'zod';

const workflow = new Workflow({
  name: 'research-and-summarize',
  triggerSchema: z.object({ topic: z.string() }),
});

const searchStep = new Step({
  id: 'search',
  execute: async ({ context }) => {
    const { topic } = context.triggerData;
    // search for topic
    return { articles: ['article1', 'article2'] };
  },
});

const summarizeStep = new Step({
  id: 'summarize',
  execute: async ({ context }) => {
    const { articles } = context.getStepResult('search');
    // summarize with LLM
    return { summary: 'Combined summary...' };
  },
});

workflow
  .step(searchStep)
  .then(summarizeStep)
  .commit();

const { runId, start } = await workflow.createRun();
const result = await start({ triggerData: { topic: 'AI frameworks 2026' } });

Built-in memory

import { Memory } from '@mastra/memory';

const memory = new Memory();  // in-memory by default; swap for Upstash, Redis, etc.

const agent = new Agent({
  name: 'AssistantWithMemory',
  instructions: 'You remember previous conversations.',
  model: openai('gpt-4o'),
  memory,
});

// First turn
await agent.generate('My name is Alex.', { threadId: 'thread-1' });

// Second turn — agent remembers Alex
const { text } = await agent.generate('What is my name?', { threadId: 'thread-1' });
// → "Your name is Alex."

Streaming in Mastra

const stream = await agent.stream('Explain quantum entanglement simply.');

for await (const chunk of stream.textStream) {
  process.stdout.write(chunk);
}

When Mastra is the right choice

  • You’re building complex multi-step agent workflows
  • You need built-in memory without wiring it up manually
  • You want deterministic workflow control (vs. the flexibility/chaos of open-ended LLM agents)
  • Observability and tracing matter from day one
  • You like Mastra’s opinionated project structure and CLI tooling

Code Comparison: RAG Pipeline

Here’s the same RAG use case across all three frameworks:

Vercel AI SDK (manual approach)

// No built-in RAG — compose your own
import { generateText, embed } from 'ai';
import { openai } from '@ai-sdk/openai';

async function ragQuery(question: string, documents: string[]) {
  // 1. Embed question
  const { embedding } = await embed({ model: openai.embedding('text-embedding-3-small'), value: question });

  // 2. Retrieve (implement your own vector similarity)
  const relevant = await vectorStore.query(embedding, 3);

  // 3. Generate
  const { text } = await generateText({
    model: openai('gpt-4o'),
    prompt: `Context: ${relevant.join('\n')}\n\nQuestion: ${question}`,
  });
  return text;
}

LangChain.js (built-in pipeline)

// Full pipeline in ~15 lines (see above)
const { answer } = await retrievalChain.invoke({ input: question });

Mastra (with RAG integration)

import { MastraVector } from '@mastra/rag';
import { openai } from '@ai-sdk/openai';

const vector = new MastraVector({ provider: 'pgvector', connectionString: process.env.DATABASE_URL });

const agent = new Agent({
  name: 'RAGAgent',
  model: openai('gpt-4o'),
  tools: {
    retrieve: createVectorQueryTool({ vectorStoreName: 'docs', topK: 3 }),
  },
});

Winner for RAG: LangChain.js has the most out-of-the-box support. Mastra is close behind with explicit vector integrations. Vercel AI SDK requires more manual wiring.


Observability Comparison

Vercel AI SDKLangChain.jsMastra
Built-in tracingNoLangSmith (hosted)Yes (local + Mastra Cloud)
Token usageVia response metadataVia callbacksBuilt-in
Step-by-step visibilityManualLangSmith traceWorkflow step history
Cost trackingManualLangSmithBuilt-in

LangSmith is the most mature observability platform, but it’s LangChain-specific. Mastra’s built-in tracing is compelling for teams that don’t want a separate SaaS dependency.


Decision Guide

Use Vercel AI SDK when:

  • Building with Next.js and streaming chat/copilot UIs
  • You want minimal abstraction and maximum control
  • Bundle size matters (SSR/edge deployments)
  • You’re fine composing your own agent/RAG logic

Use LangChain.js when:

  • You need the largest ecosystem (100+ integrations)
  • RAG pipelines are central to your product
  • You want LangSmith for evaluation and prompt management
  • Your team knows LangChain Python and wants consistency

Use Mastra when:

  • You’re building autonomous agents or multi-step workflows
  • Built-in memory is a requirement
  • You want deterministic workflow control with state machines
  • You value opinionated project structure and built-in tracing

The 2026 verdict: Vercel AI SDK for UI-heavy apps, LangChain.js for RAG-heavy pipelines, Mastra for agent-heavy workflows. There’s no single winner — the choice depends on your primary use case.


Key Takeaways

  • Vercel AI SDK excels at streaming UX and multi-model swapping — 25-line streaming chat is its signature achievement
  • LangChain.js has the deepest RAG and integration ecosystem — if your app is primarily retrieval-augmented, start here
  • Mastra’s workflow API is unique: deterministic state machines for agent pipelines with built-in memory and tracing
  • All three support tool calling with Zod schemas in 2026 — the DX is converging
  • For multi-model flexibility, Vercel AI SDK has the best provider abstraction (60+ providers via @ai-sdk/* packages)
  • Mastra leverages the AI SDK model layer internally — you can mix both in a project

Versions referenced: Vercel AI SDK 4.x, LangChain.js 0.3.x, Mastra 0.6.x. Verify latest APIs at official documentation.

Free Download

50 CLI Commands That Save Hours Every Week

The exact Git shortcuts, file search tricks, Docker commands, and productivity hacks that senior developers use daily. Compiled from 5+ years of shipping production code.

  • Git mastery (10 cmds)
  • File & search wizardry
  • Docker & DevOps tricks
  • Process & network tools
  • Productivity boosters
  • macOS & Linux install guide

No spam. 1 email/week max. Unsubscribe anytime.

Found this guide useful? Check out our free developer tools.