← Back to tutorials

TypeScript AI SDK Guide 2026: Vercel AI SDK for Next.js Applications

Build streaming AI chat interfaces, structured outputs, and agent workflows in Next.js using the Vercel AI SDK with TypeScript

TypeScript AI SDK Guide 2026: Vercel AI SDK for Next.js Applications

The Vercel AI SDK has become the standard library for building AI applications in TypeScript/Next.js. It provides a unified interface across OpenAI, Claude, Gemini, and other models, with built-in streaming, React hooks, and Server Actions support. This guide covers everything you need to build production AI features.

Why Vercel AI SDK?

  • Provider agnostic: Switch between OpenAI, Claude, Gemini with one line change
  • Streaming built-in: Text streams, object streams, UI streams
  • React hooks: useChat, useCompletion, useObject for UI
  • Server Actions: Full RSC and streaming support
  • Tool calling: Unified API across providers
  • Structured output: Schema-validated responses with Zod
  • Setup

    bash
    npm install ai @ai-sdk/openai @ai-sdk/anthropic zod
    

    or

    bun add ai @ai-sdk/openai @ai-sdk/anthropic zod

    Basic Text Generation

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

    // Server-side generation const { text } = await generateText({ model: openai('gpt-4o'), prompt: 'Explain the difference between RSC and RSC streaming in Next.js', });

    console.log(text);

    // With system prompt const { text: review } = await generateText({ model: openai('gpt-4o'), system: 'You are a senior TypeScript engineer who reviews code for best practices.', prompt: Review this code: ${code}, });

    Streaming Chat with useChat Hook

    typescript
    // src/app/chat/page.tsx
    'use client';

    import { useChat } from '@ai-sdk/react';

    export default function ChatPage() { const { messages, input, handleInputChange, handleSubmit, isLoading } = useChat({ api: '/api/chat', });

    return (

    {messages.map((message) => (
    {message.content}
    ))}

    ); }

    typescript
    // src/app/api/chat/route.ts
    import { openai } from '@ai-sdk/openai';
    import { streamText } from 'ai';

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

    const result = streamText({ model: openai('gpt-4o'), system: 'You are a helpful assistant.', messages, });

    return result.toDataStreamResponse(); }

    Structured Output with Zod

    typescript
    import { generateObject } from 'ai';
    import { openai } from '@ai-sdk/openai';
    import { z } from 'zod';

    // Define schema const ProductSchema = z.object({ name: z.string().describe('Product name'), price: z.number().describe('Price in USD'), category: z.enum(['electronics', 'clothing', 'food', 'other']), features: z.array(z.string()).describe('Key features list'), inStock: z.boolean(), rating: z.number().min(1).max(5).optional(), });

    // Extract structured data from unstructured text const { object: product } = await generateObject({ model: openai('gpt-4o'), schema: ProductSchema, prompt: `Extract product info from: "The Pro X Wireless Headphones feature 30-hour battery, active noise cancellation, and premium sound at $299. Currently in stock. User rating 4.7/5." Category: electronics`, });

    console.log(product); // { name: 'Pro X Wireless Headphones', price: 299, category: 'electronics', ... }

    Tool Calling in Next.js

    typescript
    // src/app/api/chat/route.ts
    import { openai } from '@ai-sdk/openai';
    import { streamText, tool } from 'ai';
    import { z } from 'zod';

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

    const result = streamText({ model: openai('gpt-4o'), system: 'You are a helpful shopping assistant.', messages, tools: { searchProducts: tool({ description: 'Search the product catalog', parameters: z.object({ query: z.string().describe('Search query'), category: z.enum(['electronics', 'clothing', 'all']).optional(), maxPrice: z.number().optional(), }), execute: async ({ query, category, maxPrice }) => { // Call your actual product search API const results = await searchProductCatalog({ query, category, maxPrice }); return results.slice(0, 5); }, }),

    getOrderStatus: tool({ description: 'Get order status by order ID', parameters: z.object({ orderId: z.string(), }), execute: async ({ orderId }) => { return await fetchOrderStatus(orderId); }, }), }, maxSteps: 5, // Allow up to 5 tool call rounds });

    return result.toDataStreamResponse(); }

    Streaming Object Generation

    typescript
    // Generate streaming structured data - great for forms and reports
    import { streamObject } from 'ai';
    import { openai } from '@ai-sdk/openai';

    const ReportSchema = z.object({ title: z.string(), sections: z.array(z.object({ heading: z.string(), content: z.string(), })), recommendations: z.array(z.string()), });

    // API route export async function POST(req: Request) { const { topic } = await req.json();

    const result = streamObject({ model: openai('gpt-4o'), schema: ReportSchema, prompt: Generate a business report about: ${topic}, });

    return result.toTextStreamResponse(); }

    // Client hook 'use client'; import { experimental_useObject as useObject } from '@ai-sdk/react';

    export function ReportGenerator() { const { object: report, submit, isLoading } = useObject({ api: '/api/generate-report', schema: ReportSchema, });

    return (

    {report && (

    {report.title}

    {report.sections?.map((section, i) => (

    {section?.heading}

    {section?.content}

    ))}
    )}
    ); }

    Multi-Step Agent in Next.js

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

    export async function runResearchAgent(topic: string): Promise { const { text, steps } = await generateText({ model: openai('gpt-4o'), system: `You are a research assistant. Use available tools to thoroughly research topics. Always search for information before answering. Synthesize multiple sources into a comprehensive response.`, prompt: Research and summarize: ${topic}, tools: { webSearch: tool({ description: 'Search the web for information', parameters: z.object({ query: z.string().describe('Search query'), }), execute: async ({ query }) => { // Integrate with Tavily, Serper, or another search API const results = await searchWeb(query); return results.map((r) => ({ title: r.title, snippet: r.snippet, url: r.url })); }, }), }, maxSteps: 10, // Allow multiple research iterations });

    // Log what the agent did for (const step of steps) { if (step.toolCalls) { for (const call of step.toolCalls) { console.log(Tool: ${call.toolName}, call.args); } } }

    return text; }

    Switching Models

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

    // One unified API, swap the model easily const model = process.env.AI_PROVIDER === 'anthropic' ? anthropic('claude-3-5-sonnet-20241022') : process.env.AI_PROVIDER === 'google' ? google('gemini-2.0-flash-exp') : openai('gpt-4o'); // Default

    const { text } = await generateText({ model, // Works identically regardless of provider prompt: 'Your prompt here', });

    Production Patterns

    typescript
    // Error handling and fallback
    import { generateText } from 'ai';
    import { openai } from '@ai-sdk/openai';
    import { anthropic } from '@ai-sdk/anthropic';

    async function generateWithFallback(prompt: string): Promise { const models = [ openai('gpt-4o'), anthropic('claude-3-5-sonnet-20241022'), openai('gpt-4o-mini'), // Cheaper fallback ];

    for (const model of models) { try { const { text } = await generateText({ model, prompt }); return text; } catch (error) { console.warn(Model failed, trying next:, error); } }

    throw new Error('All models failed'); }

    Conclusion

    The Vercel AI SDK dramatically reduces the boilerplate for AI applications in TypeScript. The unified API means you're not locked into a single provider, and the React hooks handle streaming complexity automatically. Start with useChat for conversational interfaces and generateObject for structured data extraction—these two patterns cover 80% of AI features teams want to build.

    Also available in 中文.