You have a Next.js app and you want to add AI features. Maybe a chatbot, maybe a content generator, maybe a smart search. The Vercel AI SDK is the most popular way to do this, and for good reason: it handles the hard parts of working with language models — streaming responses, managing conversations, and switching between providers — so you can focus on what your app actually does.

This guide walks through the Vercel AI SDK from zero to a working implementation. No prior AI experience needed. If you can build a Next.js app (or vibe code one with an AI assistant), you can follow along.

What the Vercel AI SDK Actually Does

The Vercel AI SDK is an open-source TypeScript library that sits between your app and AI model providers like OpenAI, Anthropic, Google, and others. It is not a model itself. It is the plumbing that connects your frontend to a model and handles all the messy details.

Without it, adding a streaming chat to a Next.js app means manually handling Server-Sent Events, managing token buffers, parsing partial JSON, and writing provider-specific API calls. The SDK reduces all of that to a few lines of code.

The SDK has three layers you need to understand:

This separation is the SDK's biggest advantage. You write your app logic once, and you can switch from OpenAI to Anthropic in under a minute if pricing changes or a better model launches.

Setting Up Your First AI Route

Start with a Next.js app. If you do not have one, create it with npx create-next-app@latest or ask your AI coding assistant to scaffold one for you.

Install the SDK and a provider:

npm install ai @ai-sdk/openai

You need an API key from your model provider. For OpenAI, that goes in your .env.local file as OPENAI_API_KEY. The SDK reads it automatically — no extra configuration.

Create an API route at 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'),
    messages,
  });

  return result.toDataStreamResponse();
}

That is the entire backend. The streamText function calls OpenAI, streams the response token by token, and toDataStreamResponse() converts it into a format the frontend hooks understand.

Building a Chat Interface

On the frontend, the useChat hook does most of the work. Create a component:

import { useChat } from 'ai/react';

export default function Chat() {
  const { messages, input, handleInputChange, handleSubmit, isLoading } = 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} placeholder="Ask something..." />
        <button type="submit" disabled={isLoading}>Send</button>
      </form>
    </div>
  );
}

The hook manages the full conversation: message history, streaming display, input state, and loading indicators. It automatically calls your /api/chat route and streams the response into the messages array. Each token appears as it arrives, giving that real-time typing effect users expect from AI tools.

You can customize the system prompt by passing it to streamText on the server side. Add a system parameter to tell the model what role it should play in your app. For a customer support bot, something like "You are a helpful support agent for [product]. Answer questions using only the documentation provided." For a writing assistant, adjust accordingly.

Switching Providers

This is where the SDK's architecture pays off. Say you want to try Anthropic's Claude instead of GPT-4o. Install the provider:

npm install @ai-sdk/anthropic

Then change two lines in your API route:

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

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

  const result = streamText({
    model: anthropic('claude-sonnet-4-20250514'),
    messages,
  });

  return result.toDataStreamResponse();
}

Your frontend code does not change at all. The useChat hook works identically regardless of which model is running on the backend. This makes it easy to test different models and compare quality, speed, and cost.

Available providers as of April 2026 include OpenAI, Anthropic, Google (Gemini), Mistral, Cohere, and Amazon Bedrock. Community providers cover dozens more, including local models via Ollama.

Structured Output with generateObject

Not everything is a chat interface. Sometimes you want the AI to return structured data — a JSON object with specific fields, a list of items, or a classification result. The generateObject function handles this using Zod schemas.

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

const result = await generateObject({
  model: openai('gpt-4o'),
  schema: z.object({
    name: z.string(),
    category: z.enum(['bug', 'feature', 'question']),
    priority: z.number().min(1).max(5),
    summary: z.string(),
  }),
  prompt: 'Classify this support ticket: "The login page crashes on Safari when I click the Google sign-in button"',
});

The SDK guarantees the response matches your schema. No more parsing JSON from free-text responses and hoping the model formatted it correctly. This is useful for building features like auto-categorization, data extraction, content analysis, and form pre-filling.

Tool Calling and Function Execution

Tool calling (sometimes called function calling) lets the AI model request actions from your app. Instead of just generating text, the model can say "I need to look up the weather" or "I need to search the database," and your code executes that function and feeds the result back to the model.

This is how you build AI features that actually do things, not just talk about them.

const result = streamText({
  model: openai('gpt-4o'),
  messages,
  tools: {
    getWeather: {
      description: 'Get the current weather for a city',
      parameters: z.object({
        city: z.string().describe('The city name'),
      }),
      execute: async ({ city }) => {
        const weather = await fetchWeatherAPI(city);
        return weather;
      },
    },
  },
});

When the model decides it needs weather data to answer a user's question, it calls your getWeather tool, your function fetches the data, and the model incorporates the result into its response. You can define as many tools as you need: database queries, API calls, calculations, file operations.

Tool calling is what separates a basic chatbot from an AI agent. If you are building something that needs to interact with external systems — a booking assistant, a data analyst, a project manager — this is the feature that makes it work.

Using Cursor to Write SDK Code

Here is a practical tip for vibe coders: you can use Cursor or another AI coding assistant to write Vercel AI SDK code. The SDK is well-documented enough that most AI assistants know its API well.

Effective prompts look like this:

Be specific about which provider and model you want, what the tool should do, and how the UI should look. The more context you give, the less you need to fix afterward. Review the prompting techniques guide for more strategies.

Cost Awareness: What AI Features Actually Cost

Every call to an AI model costs money. This is the part most tutorials skip, but it matters a lot when your app has real users.

Model Input (per 1M tokens) Output (per 1M tokens) Typical chat message cost
GPT-4o $2.50 $10.00 $0.01–0.03
GPT-4o mini $0.15 $0.60 $0.001–0.003
Claude Sonnet 4 $3.00 $15.00 $0.01–0.04
Gemini 2.5 Flash $0.15 $0.60 $0.001–0.003

A single chat message typically costs between $0.001 and $0.04 depending on the model and conversation length. That sounds trivial, but multiply by hundreds of users having multiple conversations per day and it adds up. A thousand users averaging 10 messages per day on GPT-4o costs roughly $100–300/month.

Strategies to manage costs:

For a deeper look at overall project costs, see the full cost breakdown guide.

Beyond Chat: Other Use Cases

The chat interface is the most common starting point, but the SDK supports much more:

The SDK's streamUI function (experimental as of April 2026) goes even further, letting the model stream React components instead of just text. Imagine asking "Show me a chart of this month's sales" and getting a rendered chart component in the chat.

Common Mistakes to Avoid

After watching vibe coders build with the AI SDK for the past year, a few patterns consistently cause problems:

Where to Deploy

The Vercel AI SDK works on any Node.js hosting, not just Vercel. It runs on Netlify, Railway, Render, and Fly.io. Vercel's edge functions are the smoothest experience since the SDK is designed for that environment, but there is no lock-in.

For streaming responses, make sure your hosting supports long-running HTTP connections. Most modern platforms do. If you are on traditional shared hosting, you may run into timeout issues with longer AI responses.

Getting Started Today

The fastest path to a working AI feature:

  1. Start with a Next.js app (new or existing).
  2. Install ai and one provider package.
  3. Create a chat API route with streamText.
  4. Add the useChat hook to a page.
  5. Set your API key in .env.local.
  6. Run the app and test it.

You can have a working streaming chat in 15 minutes. From there, add system prompts, tools, structured output, and better UI at your own pace. The SDK's documentation is thorough, and AI coding assistants can scaffold most of the boilerplate for you.

Ready to Build with AI?

Browse the complete vibe coding toolkit to find the right tools for your AI-powered app.

Browse Tools