Migrating from AI Elements
Every AI Elements component and its chatcn counterpart, including the workspace pieces that have no shadcn replacement.
On this page
AI Elements is deprecated. Most of it maps one to one onto chatcn, and the pieces with no shadcn replacement (Artifact, WebPreview, JSXPreview) ship here as Artifact, Artifact panel, Web preview and JSX preview. Names below come from the AI Elements source on GitHub.
How the APIs differ
- Plain props over parts. AI Elements composes many small parts (
WebPreviewNavigation,WebPreviewUrl,WebPreviewBody). chatcn components take props and render the whole pattern, with slots such asactionsfor what you add. - Message parts in, components out. chatcn reads AI SDK
UIMessageparts directly; helpers liketoolCallPropsFromPartmap a part to props. - One adapter for the runtime. Wire
useChatonce withuseChatcnChatand passactionsdown, instead of threading callbacks through each component. - Files install under `components/ui/chatcn/`, so they never overwrite your shadcn components and both can live side by side while you migrate.
Component map
| AI Elements | chatcn | Notes |
|---|---|---|
Artifact, ArtifactHeader, ArtifactTitle, ArtifactDescription, ArtifactActions, ArtifactAction, ArtifactClose, ArtifactContent | Artifact, Artifact panel | The card in the message and the panel are separate. ArtifactPanel has the header, actions, versions and Code/Preview built in; extra actions go in actions with ArtifactPanelAction |
WebPreview, WebPreviewNavigation, WebPreviewNavigationButton, WebPreviewUrl, WebPreviewBody, WebPreviewConsole | Web preview | One component. defaultUrl and onUrlChange carry over; history, devices, loading and crash view are built in; console messages go in logs |
JSXPreview, JSXPreviewContent, JSXPreviewError, useJSXPreview | JSX preview | jsx, components, bindings and onError carry over, isStreaming becomes streaming, the error part becomes renderError. No react-jsx-parser dependency and nothing is evaluated |
Conversation, ConversationContent, ConversationScrollButton, ConversationEmptyState, ConversationDownload | conversation, scroll-to-bottom, empty-state | Stick to bottom is built into conversation |
Message, MessageContent, MessageResponse | message, markdown | MessageResponse becomes markdown, which streams without layout shift |
MessageActions, MessageAction, MessageToolbar | message-actions | |
MessageBranch, MessageBranchContent, MessageBranchSelector, MessageBranchPrevious, MessageBranchNext, MessageBranchPage | branch-navigator | |
PromptInput and its parts | prompt-input, attachment, model-picker, send-button | IME safe Enter and Send to Stop in the same footprint are built in |
Attachments, Attachment, AttachmentPreview, AttachmentRemove | attachment | |
ModelSelector and its parts | model-picker | |
SpeechInput | dictation-button | |
Reasoning, ReasoningTrigger, ReasoningContent | reasoning | |
ChainOfThought and its parts | trace, trace-group | |
Tool, ToolHeader, ToolContent, ToolInput, ToolOutput | Tool call | Pass a part with toolCallPropsFromPart |
Confirmation and its parts | Tool call | Approval is built into the tool call: allow once, always allow, or deny with a note |
Sources, SourcesTrigger, SourcesContent, Source | sources | |
InlineCitation and its parts | citation | |
CodeBlock and its parts | code-block | |
Snippet | inline-code | |
Suggestions, Suggestion | suggestions | |
Shimmer | shimmer-text | The only shimmer chatcn allows, for status labels |
Checkpoint | checkpoint | |
Image | image | |
Terminal and its parts | terminal | |
StackTrace and its parts | stack-trace | |
TestResults and its parts | test-results | |
FileTree and its parts | file-tree | |
EnvironmentVariables and its parts | environment-variables | |
Commit and its parts | commit-card | |
Sandbox and its parts | sandbox | |
Plan, Task, Queue | Plan, Task, Queued messages | Steps with live status, expandable tasks, and messages queued while the agent works |
Context and its parts | Context meter | A ring in the composer footer with a usage breakdown on open |
Agent and its parts | Agent card | Model, tools and instructions at a glance |
Canvas, Node, Edge, Connection, Controls, Panel, Toolbar | Workflow, Canvas | Workflow draws the agent graph; Canvas is the side by side document editor |
Question | Questionnaire | One or several questions the agent asks before it continues |
Persona, AudioPlayer, Transcription, MicSelector, VoiceSelector | Voice orb, Audio player, Transcript, Voice controls, Voice picker | Microphone selection lives in Voice controls; a full call is Voice session |
OpenIn, PackageInfo, SchemaDisplay | Not included | Use JSON viewer for schemas; the others are small enough to keep from AI Elements |
Wire up useChat
import { DefaultChatTransport } from "ai"
import { useChatcnChat } from "@/hooks/use-chatcn-chat"
const { chatcnMessages, actions } = useChatcnChat({
transport: new DefaultChatTransport({ api: "/api/chat" }),
})Your /api/chat route stays as it is. See the AI SDK adapter for the action map and a mock transport for demos.