Help us improve
Share bugs, ideas, or general feedback.
From ai-elements-chatbot
Adds shadcn/ui AI chat UI components for Next.js App Router with Vercel AI SDK v5, supporting streaming responses, tool calls, reasoning visualization, and markdown rendering.
npx claudepluginhub secondsky/claude-skills --plugin ai-elements-chatbotHow this skill is triggered — by the user, by Claude, or both
Slash command
/ai-elements-chatbot:ai-elements-chatbotThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
**Status**: Production Ready ✅ | **Last Verified**: 2025-11-18
React component library for AI-powered UI: chat interfaces, tool execution visualization, reasoning displays, and workflow management. 30+ components installed via shadcn registry.
Provides Vercel AI SDK v5 React hooks (useChat, useCompletion, useObject) for streaming AI chat UIs in Next.js apps. Fixes parse stream errors, no responses, and streaming issues.
Build streaming chat interfaces with useChat hook, tool calls, and file attachments using the Vercel AI SDK.
Share bugs, ideas, or general feedback.
Status: Production Ready ✅ | Last Verified: 2025-11-18
Production-ready chat UI components for AI applications:
pnpm dlx ai-elements@latest init
pnpm dlx ai-elements@latest add message conversation response prompt-input
'use client';
import { useChat } from 'ai/react';
import { Conversation } from '@/components/ui/ai/conversation';
import { Message } from '@/components/ui/ai/message';
import { Response } from '@/components/ui/ai/response';
import { PromptInput } from '@/components/ui/ai/prompt-input';
export default function ChatPage() {
const { messages, input, handleInputChange, handleSubmit } = useChat({
api: '/api/chat'
});
return (
<div className="flex h-screen flex-col">
<Conversation>
{messages.map((msg) => (
<Message key={msg.id} role={msg.role}>
<Response markdown={msg.content} />
</Message>
))}
</Conversation>
<PromptInput
value={input}
onChange={handleInputChange}
onSubmit={handleSubmit}
/>
</div>
);
}
Load references/setup-guide.md for complete setup.
import { Conversation } from '@/components/ui/ai/conversation';
import { Message } from '@/components/ui/ai/message';
<Conversation>
{messages.map((msg) => (
<Message key={msg.id} role={msg.role}>
{msg.content}
</Message>
))}
</Conversation>
import { Response } from '@/components/ui/ai/response';
<Response markdown={content} />
import { PromptInput } from '@/components/ui/ai/prompt-input';
<PromptInput
value={input}
onChange={handleInputChange}
onSubmit={handleSubmit}
/>
import { CodeBlock } from '@/components/ui/ai/code-block';
<CodeBlock code={code} language="typescript" />
import { Reasoning } from '@/components/ui/ai/reasoning';
<Reasoning content={thinking} />
import { Tool } from '@/components/ui/ai/tool';
<Tool name="search" args={{ query: "..." }} result={result} />
pnpm dlx ai-elements@latest)Core:
Content:
Actions:
Advanced:
const { messages, input, handleInputChange, handleSubmit } = useChat();
return (
<>
<Conversation>
{messages.map(m => (
<Message key={m.id} role={m.role}>
<Response markdown={m.content} />
</Message>
))}
</Conversation>
<PromptInput value={input} onChange={handleInputChange} onSubmit={handleSubmit} />
</>
);
{messages.map(m => (
<Message key={m.id} role={m.role}>
{m.toolInvocations?.map(tool => (
<Tool key={tool.toolCallId} name={tool.toolName} args={tool.args} result={tool.result} />
))}
<Response markdown={m.content} />
</Message>
))}
<Message role="assistant">
{reasoning && <Reasoning content={reasoning} />}
<Response markdown={content} />
</Message>
<Response markdown={content}>
{(node) => node.type === 'code' ? (
<CodeBlock code={node.value} language={node.lang} />
) : null}
</Response>
<Message role="assistant">
<Response markdown={content} />
<Sources sources={sources} />
</Message>
// app/api/chat/route.ts
import { streamText } from 'ai';
import { openai } from '@ai-sdk/openai';
export async function POST(req: Request) {
const { messages } = await req.json();
const result = streamText({
model: openai('gpt-4'),
messages
});
return result.toDataStreamResponse();
}
const result = streamText({
model: openai('gpt-4'),
messages,
tools: {
search: {
description: 'Search the web',
parameters: z.object({ query: z.string() }),
execute: async ({ query }) => {
return await search(query);
}
}
}
});
Use when:
Don't use when:
References (references/):
component-catalog.md - All 8 AI Elements components with examplesexample-reference.md - Complete integration examples and patternssetup-guide.md - Step-by-step setup with Next.js 15 and shadcn/uiTemplates (templates/):
Questions? Issues?
references/setup-guide.md for complete setup