Stop Rebuilding UI

Shadcn.io is not affiliated with official shadcn/ui

React Components for Conversational AI

Open-source React components for building ChatGPT-style AI chat interfaces. Production-ready UI with TypeScript, Vercel AI SDK support, streaming responses, tool calls, and shadcn/ui design.

You've seen how ChatGPT, Claude, and Gemini handle conversations. The streaming text. The collapsible reasoning. The tool call displays. The message branching when you regenerate. Now you need to build the same thing.

The problem? Generic React UI libraries weren't designed for AI. You end up writing custom components for every AI-specific pattern—streaming markdown, tool execution displays, reasoning blocks, citation lists. Then you maintain all of it.

These components solve that. 25+ purpose-built React components for conversational AI interfaces. They integrate with the Vercel AI SDK, follow shadcn/ui's copy-paste philosophy, and handle every pattern you've seen in production AI apps.

The Problem with Building AI Interfaces

When you start building a ChatGPT-style app with standard React components, you quickly hit walls:

Streaming responses — Regular text components don't handle markdown that renders character by character without flickering. You need a component that buffers, parses, and renders streaming content smoothly.

Tool calls — The AI SDK gives you tool-call and tool-result parts, but you need UI that shows what function is running, what inputs it received, and what it returned. With loading states. And error handling.

Reasoning/thinking — Models like Claude and o1 emit thinking tokens. You need collapsible blocks that show "Thought for 12 seconds" and expand to reveal the reasoning. That auto-collapse when streaming finishes.

Message branching — When users regenerate a response, you store multiple versions. Now you need UI to navigate between them: "2 of 3" with Previous/Next buttons.

Citations — Grounded responses include source links. You need expandable citation lists that don't clutter the message but are accessible when needed.

Each of these is a custom implementation with standard libraries. With these components, they're one import away.

Why shadcn/ui for AI Components?

The shadcn/ui approach works perfectly for AI interfaces:

You own the code — Every component copies into your project. When your designer says "make the reasoning block purple," you open the file and change it. No waiting for library updates. No fighting with CSS overrides.

Composable architecture — Mix and match components. Use Message without Conversation. Use Tool without the full chat interface. Each component is independent.

Familiar patterns — If you've used shadcn/ui, you already know how these work. Tailwind classes, Radix primitives, TypeScript props. Same development experience.

AI SDK integration — Components understand Vercel AI SDK data structures. Pass message.parts and they render text, tool calls, and reasoning automatically.


Examples

Complete interfaces showing how components work together.


Core Chat Components

The foundation of any conversational AI interface.


AI Response Components

Handle the patterns unique to AI—tool calls, reasoning, citations, and response variations.


Loading & Progress

Visual feedback for streaming, background operations, and multi-step tasks.


Code & Content

Display code blocks, generated artifacts, and rich content.


User Interaction

Components for confirmations, context, and user decisions.


How It Works with Vercel AI SDK

The AI SDK handles state management and streaming. These components handle rendering. They work together seamlessly.

import { Message, MessageContent, MessageResponse } from "@/components/ai/message";
import { Conversation, ConversationContent } from "@/components/ai/conversation";
import { Tool } from "@/components/ai/tool";
import { Reasoning } from "@/components/ai/reasoning";
import { useChat } from "@ai-sdk/react";

export default function Chat() {
  const { messages } = useChat();

  return (
    <Conversation>
      <ConversationContent>
        {messages.map((message) => (
          <Message from={message.role} key={message.id}>
            <MessageContent>
              {message.parts?.map((part, i) => {
                if (part.type === "text")
                  return <MessageResponse key={i}>{part.text}</MessageResponse>;
                if (part.type === "tool-call")
                  return <Tool key={i} name={part.toolName} status="complete" />;
                if (part.type === "reasoning")
                  return <Reasoning key={i}>{part.reasoning}</Reasoning>;
              })}
            </MessageContent>
          </Message>
        ))}
      </ConversationContent>
    </Conversation>
  );
}

No manual stream parsing. No custom scroll handling. No reimplementing tool call displays. The SDK manages the AI, the components manage the UI.


Frequently Asked Questions

Was this page helpful?

Sign in to leave feedback.