Articles

A Complete Guide to Vercel's AI SDK

What is Vercel AI SDK

Vercel AI SDK is a powerful TypeScript-first toolkit that provides a unified interface for building AI applications with Next.js and other modern frameworks. It eliminates the traditional complexity of managing multiple provider APIs, handling different response formats, and implementing streaming logic.

The AI SDK is comprised of three main parts: AI SDK Core, AI SDK UI, and AI SDK RSC.

  • AI SDK Core handles server-side AI operations with functions like generateText for creating text responses, streamText for streaming responses, generateObject for structured data generation, and streamObject for streaming structured data.
  • AI SDK UI provides client-side hooks for building interactive interfaces. It includes useChat for real-time streaming of chat messages, useCompletion for handling text completions, useObject for consuming streamed JSON objects, and useAssistant for interactive assistant features. These hooks manage state and handle streaming data automatically.
  • AI SDK RSC enables React Server Component integration for streaming UI elements directly from the server. However, development is currently experimental, and they recommend using the AI SDK UI for production applications.

You can easily switch between different AI providers like OpenAI, Google, or Anthropic. To do this, you only need to change the provider import and the model you want to use. The AI SDK UI works with popular web frameworks like React, Svelte, Vue.js, and Angular.

Now that we have the basics covered, let’s set up a development environment to start working with the Vercel AI SDK.

Setting up Vercel AI SDK in your Next.js project

The setup process requires Node.js 18 or higher and basic Next.js knowledge. We’ll configure the environment for Google AI integration and build upon this project throughout the article using current production models.

Creating a Next.js project

Create a new Next.js project with TypeScript:

npx create-next-app@latest ai-demo
cd ai-demo

When you run the create-next-app command, you’ll be prompted with several configuration options:

  • Would you like to use TypeScript? Select Yes
  • Which linter would you like to use? Select ESLint (default)
  • Would you like to use Tailwind CSS? Select Yes
  • Would you like your code inside a src/ directory? Select No
  • Would you like to use App Router? (recommended) Select Yes
  • Would you like to use Turbopack? (recommended) Select Yes
  • Would you like to customize the import alias (@/* by default)? Select No

After completing these prompts, Next.js will install the necessary packages and set up your project with the selected configuration.

After creating the project, the directory structure looks like this:

ai-demo/
├── app/
│ ├── favicon.ico
│ ├── globals.css
│ ├── layout.tsx
│ └── page.tsx
├── public/
│ ├── next.svg
│ └── vercel.svg
├── .eslintrc.json
├── .gitignore
├── next.config.mjs
├── package.json
├── postcss.config.mjs
├── README.md
├── tailwind.config.ts
└── tsconfig.json

Installing required packages

Install the AI SDK packages:

npm install ai @ai-sdk/google @ai-sdk/react

The ai package contains AI SDK Core functionality, @ai-sdk/google provides Google AI provider integration, and @ai-sdk/react contains the React-specific UI hooks.

Obtaining Google AI API key

To use Google’s AI models, we need an API key:

  1. Navigate to Google AI Studio
  2. Sign in with your Google account
  3. Click “Get API key” from the left panel
  4. In the Create API key dialog, you’ll see two options:
    • Create API key in a new project
    • Create API key in existing project (requires selecting an existing Google Cloud project)
  5. If choosing an existing project, search for and select the Google Cloud project you want to use
  6. Once generated, copy the API key and store it securely

Google has a free tier that is great for development and testing. This makes it a good option for beginners.

Setting up environment variables

Create an environment file .env.local in the project root. Next.js has built-in support for loading environment variables from .env files:

GOOGLE_GENERATIVE_AI_API_KEY=your_api_key_here

The Google provider looks for the GOOGLE_GENERATIVE_AI_API_KEY environment variable by default. Use the .env.local file for local development, but don’t commit it to version control. Next.js automatically adds all .env files to .gitignore. Environment variables that don’t start with the NEXT_PUBLIC_ prefix are only accessible on the server side. This makes them suitable for API keys and other sensitive information.

Let’s start the development server to verify everything is working:

npm run dev

Navigate to http://localhost:3000 to see your Next.js application running. The development environment is now configured for AI SDK integration. Next, we’ll implement the first AI feature using the core SDK functions.

Building your first AI feature with Vercel AI SDK core

AI SDK Core has two main functions for generating text: generateText and streamText. We will use generateText to create a simple text generation feature. This function is best for situations where we need a complete response at once.

Step 1: Create the API route

Create an API route at app/api/generate/route.ts:

import { generateText } from "ai";
import { google } from "@ai-sdk/google";
export async function POST(req: Request) {
const { prompt } = await req.json();
const { text } = await generateText({
model: google("gemini-1.5-flash"),
prompt: prompt,
maxOutputTokens: 200,
});
return Response.json({ text });
}

This API route takes a prompt from the frontend, uses the generateText function with the Google AI model, and sends back the text that was generated.

The result from generateText includes important details: text (the generated text), usage (information on token usage), finishReason (the reason the model stopped), and response (extra data about the response).

Note: We’re using gemini-1.5-flash, which is one of Google’s current production models. You can find the full list of available models in Vercel’s Google AI Models documentation.

Step 2: Build the frontend interface

Replace the content in app/page.tsx:

"use client";
import { useState } from "react";
export default function Home() {
const [prompt, setPrompt] = useState("");
const [result, setResult] = useState("");
const [loading, setLoading] = useState(false);
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
setLoading(true);
try {
const response = await fetch("/api/generate", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ prompt }),
});
const data = await response.json();
setResult(data.text);
} catch (error) {
console.error("Error:", error);
} finally {
setLoading(false);
}
};
return (
<div className="max-w-2xl mx-auto p-6 min-h-screen bg-gray-50">
<h1 className="text-3xl font-light text-gray-800 mb-8">
AI Text Generator
</h1>
<form onSubmit={handleSubmit} className="space-y-6">
<textarea
value={prompt}
onChange={(e) => setPrompt(e.target.value)}
placeholder="Enter your prompt..."
className="w-full p-4 border border-gray-200 rounded-lg focus:ring-2 focus:ring-gray-300 focus:border-transparent outline-none resize-none transition-all"
rows={4}
/>
<button
type="submit"
disabled={loading}
className="px-6 py-3 bg-gray-800 text-white rounded-lg hover:bg-gray-700 disabled:bg-gray-400 disabled:cursor-not-allowed transition-colors font-medium"
>
{loading ? "Generating..." : "Generate"}
</button>
</form>
{result && (
<div className="mt-8 p-6 bg-white border border-gray-200 rounded-lg shadow-sm">
<h3 className="text-lg font-medium text-gray-700 mb-4">
Generated Text:
</h3>
<div className="text-gray-600 leading-relaxed whitespace-pre-wrap break-words">
{result}
</div>
</div>
)}
</div>
);
}

This interface includes a text area for prompt input, a submit button with a loading state, and a results display area. The form handles submission, makes API calls, and displays responses.

Step 3: Test the implementation

Start the development server and test the feature:

npm run dev

Go to http://localhost:3000 and type a prompt like “Write a short poem about programming.” The app will use the Google AI model to create responses.

Vercel AI SDK App output

This implementation shows basic concepts. However, users want instant responses instead of waiting for everything to generate. Let’s improve the experience by adding streaming to the same project.

Integrating AI SDK UI for streaming and better user experience

Our current setup works well, but it can take a large language model up to a minute to generate a response, depending on the model and prompt. This delay is not acceptable for interactive uses like chatbots or real-time applications, where users want immediate answers.

To improve this, we can add streaming functionality using the streamText function, which is made for these interactive situations.

Upgrading the API route for streaming

Modify the existing API route app/api/generate/route.ts to add streaming capability:

import { streamText } from "ai";
import { google } from "@ai-sdk/google";
export async function POST(req: Request) {
const { prompt } = await req.json();
const result = streamText({
model: google("gemini-1.5-flash "),
prompt: prompt,
maxOutputTokens: 200,
});
return result.toUIMessageStreamResponse();
}

Instead of using generateText, which waits for the complete response, streamText immediately starts streaming and provides a more responsive experience.

The streamText function provides several promises that resolve when the stream is finished, including text (the complete generated text), usage (token usage information), and finishReason (why the model stopped).

Upgrading the frontend for real-time updates

Now let’s enhance the frontend in app/page.tsx to handle streaming responses:

"use client";
import { useCompletion } from "@ai-sdk/react";
export default function Home() {
const { completion, input, handleInputChange, handleSubmit, isLoading } =
useCompletion({
api: "/api/generate",
});
return (
<div className="max-w-2xl mx-auto p-6 min-h-screen bg-gray-50">
<h1 className="text-3xl font-light text-gray-800 mb-8">
AI Text Generator
</h1>
<form onSubmit={handleSubmit} className="space-y-6">
<textarea
value={input}
onChange={handleInputChange}
placeholder="Enter your prompt..."
className="w-full p-4 border border-gray-200 rounded-lg focus:ring-2 focus:ring-gray-300 focus:border-transparent outline-none resize-none transition-all"
rows={4}
/>
<button
type="submit"
disabled={isLoading}
className="px-6 py-3 bg-gray-800 text-white rounded-lg hover:bg-gray-700 disabled:bg-gray-400 disabled:cursor-not-allowed transition-colors font-medium"
>
{isLoading ? "Generating..." : "Generate"}
</button>
</form>
{completion && (
<div className="mt-8 p-6 bg-white border border-gray-200 rounded-lg shadow-sm">
<h3 className="text-lg font-medium text-gray-700 mb-4">
Generated Text:
</h3>
<div className="text-gray-600 leading-relaxed whitespace-pre-wrap break-words">
{completion}
</div>
</div>
)}
</div>
);
}

GIF of text streaming

The useCompletion hook simplifies state management by automatically handling streaming responses. It takes care of the prompt input and updates the interface in real-time as new text comes from the API. The completion value changes gradually as tokens stream in, making for a more engaging user experience.

Benefits of the streaming upgrade

The streaming method has some important benefits compared to the basic way of generating text:

  • Quick responses - Users can see replies appear little by little instead of waiting a long time.
  • Feels faster - Even if it takes the same time, people think they get answers more quickly.
  • Smart use of resources - It only creates new parts when needed.
  • Extra features - It can handle errors and make changes in the stream.

Our streaming function is working well. Now, let’s add flexibility for providers to our project.

Switching AI providers with Vercel SDK AI

AI SDK Core makes it easy to set up prompts and settings in a consistent way, so we can work with different models easily. We will also expand our current project to support multiple providers.

Install additional provider packages:

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

Add API keys to the existing .env.local file:

OPENAI_API_KEY=your_openai_key
ANTHROPIC_API_KEY=your_anthropic_key

Each provider looks for specific environment variable names by default. OpenAI uses OPENAI_API_KEY, and Anthropic uses ANTHROPIC_API_KEY. Update the API route app/api/generate/route.ts to support provider switching:

import { streamText } from "ai";
import { google } from "@ai-sdk/google";
import { openai } from "@ai-sdk/openai";
import { anthropic } from "@ai-sdk/anthropic";
const models = {
google: google("gemini-1.5-flash"),
openai: openai("gpt-4o-mini"),
anthropic: anthropic("claude-3-5-haiku-latest"),
};
export async function POST(req: Request) {
const { prompt, provider = "google" } = await req.json()
if (!prompt) {
return new Response("Prompt is required", { status: 400 });
}
const model = models[provider as keyof typeof models];
if (!model) {
return new Response("Invalid provider", { status: 400 });
}
const result = streamText({
model,
prompt,
maxOutputTokens: 200,
});
return result.toUIMessageStreamResponse();
}

This configuration maps provider names to their respective model instances. We’re using current production models: gemini-1.5-flash for Google, gpt-4o-mini for OpenAI, and claude-3-5-haiku-latest for Anthropic. Switching between providers requires changing only the model specification while maintaining the same interface.

Update app/page.tsx to include provider selection:

"use client";
import { useCompletion } from "@ai-sdk/react";
import { useState } from "react";
export default function Home() {
const [provider, setProvider] = useState("google");
const { completion, input, handleInputChange, handleSubmit, isLoading } =
useCompletion({
api: "/api/generate",
body: { provider },
});
return (
<div className="max-w-2xl mx-auto p-6 min-h-screen bg-gray-50">
<h1 className="text-3xl font-light text-gray-800 mb-8">
AI Text Generator
</h1>
<form onSubmit={handleSubmit} className="space-y-6">
<div>
<label className="block text-sm font-medium text-gray-700 mb-2">
AI Provider:
</label>
<select
value={provider}
onChange={(e) => setProvider(e.target.value)}
className="w-full p-3 border border-gray-200 rounded-lg focus:ring-2 focus:ring-gray-300 focus:border-transparent outline-none transition-all"
>
<option value="google">Google Gemini 1.5 Flash</option>
<option value="openai">OpenAI GPT-4o Mini</option>
<option value="anthropic">Anthropic Claude 3.5 Haiku</option>
</select>
</div>
<textarea
value={input}
onChange={handleInputChange}
placeholder="Enter your prompt..."
className="w-full p-4 border border-gray-200 rounded-lg focus:ring-2 focus:ring-gray-300 focus:border-transparent outline-none resize-none transition-all"
rows={4}
/>
<button
type="submit"
disabled={isLoading}
className="px-6 py-3 bg-gray-800 text-white rounded-lg hover:bg-gray-700 disabled:bg-gray-400 disabled:cursor-not-allowed transition-colors font-medium"
>
{isLoading ? "Generating..." : "Generate"}
</button>
</form>
{completion && (
<div className="mt-8 p-6 bg-white border border-gray-200 rounded-lg shadow-sm">
<h3 className="text-lg font-medium text-gray-700 mb-4">
Generated Text (using {provider}):
</h3>
<div className="text-gray-600 leading-relaxed whitespace-pre-wrap break-words">
{completion}
</div>
</div>
)}
</div>
);
}

The provider selection dropdown allows users to compare responses from different models using the same prompt. This demonstrates the flexibility of the unified interface.

To test the multi-provider feature, choose different providers and submit the same prompt. Each provider will give a different response but will use the same code patterns.

Vercel AI SDK provider selection screen

Different providers offer different features. Google has good free options and supports many languages. OpenAI provides reliable models that can do many tasks and give clear outputs. Anthropic focuses on creating helpful, safe, and honest AI responses with strong reasoning skills.

Our project shows the main features of the Vercel AI SDK: text generation, streaming, and flexibility with providers.

Conclusion

The Vercel AI SDK helps you easily add AI features to web applications. We created a text generation app that highlights two main parts: AI SDK Core for server-side tasks and AI SDK UI for client-side interactions.

Our app demonstrates how the generateText and streamText functions work with different AI providers through a single set of APIs. The useCompletion hook simplifies the use of streaming responses and state ma

If you want to understand how generative AI works, consider taking this free Intro to Generative AI course. It will help you build a strong foundation in AI basics and improve your development skills.

Frequently asked questions

1. Is Vercel AI SDK free to use?

Yes, Vercel AI SDK is free and open-source. However, AI providers charge for model usage based on tokens processed. Google offers free tiers suitable for development, while OpenAI and Anthropic have paid usage models.

2. Should I use Vercel AI SDK

Yes, if you’re building AI applications in Next.js and want unified provider interfaces, streaming support, and TypeScript integration.

3. What are some Vercel AI SDK examples?

The official documentation includes examples for chatbots, completion interfaces, structured data generation, and multi-modal applications. The GitHub repository contains starter templates for different frameworks and use cases.

4. Is Vercel AI SDK open-source?

Yes, Vercel AI SDK is open-source and available on GitHub. The community contributes features, bug fixes, and new provider integrations. The library is maintained by the Vercel team with community support.

Codecademy Team

'The Codecademy Team, composed of experienced educators and tech experts, is dedicated to making tech skills accessible to all. We empower learners worldwide with expert-reviewed content that develops and enhances the technical skills needed to advance and succeed in their careers.'

Meet the full team

Learn more on Codecademy