Build React chat interfaces with Vercel AI SDK v6. Covers useChat/useCompletion/useObject hooks, message parts structure, tool approval workflows, and 18 UI error solutions. Prevents documented issues with React Strict Mode, concurrent requests, stale closures, and tool approval edge cases. Use when: implementing AI chat UIs, migrating v5→v6, troubleshooting "useChat failed to parse stream", "stale body values", "React maximum update depth", "Cannot read properties of undefined (reading 'state')", or tool approval workflow errors.
View on GitHubSelect agents to install to:
npx add-skill https://github.com/jezweb/claude-skills/blob/main/skills/ai-sdk-ui/SKILL.md -a claude-code --skill ai-sdk-uiInstallation paths:
.claude/skills/ai-sdk-ui/# AI SDK UI - Frontend React Hooks
Frontend React hooks for AI-powered user interfaces with Vercel AI SDK v6.
**Version**: AI SDK v6.0.42 (Stable)
**Framework**: React 18+/19, Next.js 14+/15+
**Last Updated**: 2026-01-20
---
## AI SDK v6 Stable (January 2026)
**Status:** Stable Release
**Latest:** ai@6.0.42, @ai-sdk/react@3.0.44, @ai-sdk/openai@3.0.7
**Migration:** Minimal breaking changes from v5 → v6
### New UI Features in v6
**1. Message Parts Structure (Breaking Change)**
In v6, message content is now accessed via `.parts` array instead of `.content`:
```tsx
// ❌ v5 (OLD)
{messages.map(m => (
<div key={m.id}>{m.content}</div>
))}
// ✅ v6 (NEW)
{messages.map(m => (
<div key={m.id}>
{m.parts.map((part, i) => {
if (part.type === 'text') return <span key={i}>{part.text}</span>;
if (part.type === 'tool-invocation') return <ToolCall key={i} tool={part} />;
if (part.type === 'file') return <FilePreview key={i} file={part} />;
return null;
})}
</div>
))}
```
**Part Types:**
- `text` - Text content with `.text` property
- `tool-invocation` - Tool calls with `.toolName`, `.args`, `.result`
- `file` - File attachments with `.mimeType`, `.data`
- `reasoning` - Model reasoning (when available)
- `source` - Source citations
**3. Agent Integration**
Type-safe messaging with agents using `InferAgentUIMessage<typeof agent>`:
```tsx
import { useChat } from '@ai-sdk/react';
import type { InferAgentUIMessage } from 'ai';
import { myAgent } from './agent';
export default function AgentChat() {
const { messages, sendMessage } = useChat<InferAgentUIMessage<typeof myAgent>>({
api: '/api/chat',
});
// messages are now type-checked against agent schema
}
```
**4. Tool Approval Workflows (Human-in-the-Loop)**
Request user confirmation before executing tools:
```tsx
import { useChat } from '@ai-sdk/react';
import { useState } from 'react';
export default function ChatWithApproval() {
const { messages, sendMessage, addToolApp