Vercel AI SDK Best Practices
Ten practices for streaming chat, generative tool UI, approvals, and edge-friendly deploy of full-stack web agents with the Vercel AI SDK.
Use this list when reviewing a Next.js agent PR or hardening a chat route before production.
How to Use This Checklist
- Work A → D: protocol and chat first, then tools/UI, then safety, then deploy/ops.
- Tick an item only when it is true in code or runbooks, not as a hope.
- Re-check after AI SDK major upgrades (part types, transports, approval APIs move).
- Pair with The Vercel AI SDK Mental Model: Streaming UI Meets Agent Loops for the why.
A - Streaming Chat Foundations
- 1. Render
message.parts, not a single content string. Text, tools, data, and approvals all travel as parts; content-only UIs hide generative UI. - 2. Convert UI messages at the server boundary. Use
convertToModelMessages(or current helper) beforestreamText; never send raw UI metadata as if it were provider format. - 3. Bound every multi-step loop. Set
stopWhen/ step caps andmaxDurationso tools cannot run until the platform kills the function. - 4. Drive UX from
statusand errors. Disable send whilesubmitted/streaming, offer Stop, and show a generic Retry path without leaking server details.
B - Tools and Generative UI
- 5. Treat each tool as an allowlisted UI capability. Clear
description+ ZodinputSchema; maptool-${name}part states to components (loading, result, error). - 6. Keep secrets and side effects on the server. Use
executefor privileged tools; client tools only for device/UI concerns withaddToolOutput. - 7. Gate irreversible tools with approval states. AI SDK 6+ approval (
needsApproval/toolApproval) plusaddToolApprovalResponse; re-validate policy on the second pass.
C - Safety and Trust
- 8. Treat client message history as untrusted input. Re-check authz, schema, and approval bindings server-side; consider approval signing secrets for high-risk tools.
- 9. Authenticate before tools and rate-limit
/api/chat. Authorize from session cookies or verified tokens, not a user id field in the JSON body.
D - Deploy and Interop
- 10. Choose Edge vs Node deliberately. Edge for lean streaming chat; Node for native deps and long workflows. Start the stream quickly; pin env keys per environment.
- 11. Pin AI SDK majors across UI and backends. When proxying to Pydantic AI / LangGraph, align stream protocol /
sdk_versionwith@ai-sdk/react. - 12. Log step, tool, model, and stop reason with redaction. You cannot debug wrong tool UI or cost spikes without traces.
Applying the Habits in Order
| Stage | Habits | Exit criterion |
|---|---|---|
| Prototype | 1-4 | Streaming chat works with parts + status |
| Productize | 5-7 | Tools render; writes need approval |
| Secure | 8-9 | Authn/z + untrusted history model |
| Operate | 10-12 | Runtime, versions, and traces production-ready |
Quick Anti-Patterns
handleSubmittutorials from old majors mixed with AI SDK 6 transports without reading migration notes.- Auto-running
refund/delete/shelltools with no approval. - Edge route importing Node-only PDF or DB native clients.
- Browser holding provider API keys.
- Python upstream double-wrapped in a second custom SSE encoder.
- Unbounded tool loops "until the model stops."
- Logging full prompts and tool args to a shared slack channel.
Minimal Reference Snippet
// Pattern: edge-safe stream + tool + step cap (verify APIs at build)
import {
convertToModelMessages,
isStepCount,
streamText,
tool,
type UIMessage,
} from "ai";
import { z } from "zod";
export const runtime = "edge";
export const maxDuration = 30;
export async function POST(req: Request) {
const { messages }: { messages: UIMessage[] } = await req.json();
// authenticate(req) here
const result = streamText({
model: "openai/gpt-4o-mini",
messages: await convertToModelMessages(messages),
stopWhen: isStepCount(5),
tools: {
getStatus: tool({
description: "Return a simple status payload for UI",
inputSchema: z.object({ label: z.string() }),
execute: async ({ label }) => ({ label, ok: true }),
}),
},
});
return result.toUIMessageStreamResponse();
}FAQs
Which three habits are non-negotiable?
Parts-based rendering (1), loop/duration bounds (3), and server-side trust/auth for tools (8-9).
Do all apps need tool approval?
No. Read-only demos can skip it. Any tool that writes, spends, or exfiltrates needs a gate.
Is Edge always the right deploy target?
No. Prefer Edge for simple streaming chat with fetch-based providers. Prefer Node for heavy agents.
How often should we revisit this list?
On every AI SDK major bump, after a production agent incident, and when adding a new write tool.
Can these practices apply without Next.js?
Yes. SameChat transport + Core patterns work on other hosts; Vercel Edge specifics apply only on Vercel/Next.
Where do workflow patterns fit?
Use chains/routing/evaluator-optimizer when free tool loops are too unreliable; still apply bounds, logging, and auth.
What should tech leads require in PRs?
Parts rendering, stopWhen/maxDuration, no browser secrets, approval on write tools, and a note on Edge vs Node choice.
How do we test streaming in CI?
Contract-test the route with mocked model streams when possible; smoke-test previews for real provider streams.
What is the biggest upgrade footgun?
Assuming v4/v5 chat APIs (api option, input from the hook, content rendering) still match AI SDK 6 transports and parts.
How does this relate to Python agents?
UI habits still apply; add protocol version alignment and a single streaming proxy (habit 11).
Related
- The Vercel AI SDK Mental Model: Streaming UI Meets Agent Loops - architecture
- Vercel AI SDK Basics - starter examples
- Tool Calling and UI Generation with the AI SDK - generative UI
- AI SDK 6's Tool-Approval States for Human-in-the-Loop Agents - HITL
- Chaining, Routing, and Evaluator-Optimizer Agent Patterns - workflows
- Deploying an AI SDK Agent to Vercel Edge Functions - edge deploy
- Integrating Pydantic AI or LangGraph Behind an AI SDK Frontend - Python backends
Stack versions: Pins from the category manifest (verify at build): OpenRouter (~315+ models, July 2026 pricing/fees); LangGraph 1.0+; CrewAI 1.14+; Microsoft Agent Framework 1.0; Vercel AI SDK 6; Pydantic AI (latest); LlamaIndex (latest); OpenAI Agents SDK (latest + MCP); MCP (Linux Foundation governance); A2A (HTTP+SSE+JSON-RPC 2.0); Solana
@solana/web3.js+@solana/spl-token.