Thread
A complete chat interface that combines message rendering, auto-scrolling, composer input, attachments, and conditional UI states. Fully customizable and composable.
Anatomy
The Thread component is built with the following primitives:
import { ThreadPrimitive } from "@assistant-ui/react";
<ThreadPrimitive.Root>
<ThreadPrimitive.Viewport>
<ThreadPrimitive.Empty />
<ThreadPrimitive.Messages
components={{
EditComposer,
UserMessage,
AssistantMessage,
}}
/>
<ThreadPrimitive.ScrollToBottom />
</ThreadPrimitive.Viewport>
<ThreadPrimitive.Suggestion />
<ThreadPrimitive.If />
</ThreadPrimitive.Root>
Getting Started
Add the component
npx assistant-ui@latest add thread
npx shadcn@latest add @assistant-ui/thread
npx shadcn@latest add "https://r.assistant-ui.com/thread"
This adds a /components/assistant-ui/thread.tsx
file to your project, which you can adjust as needed.
Use in your application
import { Thread } from "@/components/assistant-ui/thread";
export default function Chat() {
return (
<div className="h-full">
<Thread />
</div>
);
}
Examples
Welcome Screen
<ThreadPrimitive.If empty>
<ThreadWelcome />
</ThreadPrimitive.If>
Viewport Spacer
<ThreadPrimitive.If empty={false}>
<div className="min-h-8 grow" />
</ThreadPrimitive.If>
Conditional Send/Cancel Button
<ThreadPrimitive.If running={false}>
<ComposerPrimitive.Send>
Send
</ComposerPrimitive.Send>
</ThreadPrimitive.If>
<ThreadPrimitive.If running>
<ComposerPrimitive.Cancel>
Cancel
</ComposerPrimitive.Cancel>
</ThreadPrimitive.If>
Suggestions
<ThreadPrimitive.Suggestion
prompt="What's the weather in San Francisco?"
send
/>
API Reference
The following primitives are used within the Thread component and can be customized in your /components/assistant-ui/thread.tsx
file.
Root
Contains all parts of the thread.
ThreadPrimitiveRootProps
asChild:
Merge props with child element instead of rendering a wrapper div.
className?:
CSS class name.
This primitive renders a <div>
element unless asChild
is set.
Viewport
The scrollable area containing all messages. Automatically scrolls to the bottom as new messages are added.
ThreadPrimitiveViewportProps
asChild:
Merge props with child element instead of rendering a wrapper div.
autoScroll:
Whether to automatically scroll to the bottom when new messages are added while the viewport was previously scrolled to the bottom.
className?:
CSS class name.
This primitive renders a <div>
element unless asChild
is set.
Messages
Renders all messages in the thread. This primitive renders a separate component for each message.
<ThreadPrimitive.Messages
components={{
UserMessage: UserMessage,
EditComposer: EditComposer,
AssistantMessage: AssistantMessage,
}}
/>
ThreadPrimitiveMessagesProps
components:
Components to render for different message types.
MessageComponents
Message?:
Default component for all messages.
UserMessage?:
Component for user messages.
EditComposer?:
Component for user messages being edited.
AssistantMessage?:
Component for assistant messages.
SystemMessage?:
Component for system messages.
MessageByIndex
Renders a single message at the specified index.
<ThreadPrimitive.MessageByIndex
index={0}
components={{
UserMessage: UserMessage,
AssistantMessage: AssistantMessage
}}
/>
ThreadPrimitiveMessageByIndexProps
index:
The index of the message to render.
components?:
Components to render for different message types.
Empty
Renders children only when there are no messages in the thread.
ThreadPrimitiveEmptyProps
children?:
Content to display when the thread is empty.
ScrollToBottom
A button to scroll the viewport to the bottom. Disabled when the viewport is already at the bottom.
ThreadPrimitiveScrollToBottomProps
asChild:
Merge props with child element instead of rendering a wrapper button.
className?:
CSS class name.
This primitive renders a <button>
element unless asChild
is set.
Suggestion
Shows a suggestion to the user. When clicked, replaces the composer's value with the suggestion and optionally sends it.
<ThreadPrimitive.Suggestion
prompt="Tell me about React hooks"
send
/>
ThreadPrimitiveSuggestionProps
prompt:
The suggestion text to use when clicked.
send?:
When true, automatically sends the message. When false, replaces or appends the composer text with the suggestion - depending on the value of `clearComposer`
clearComposer:
Whether to clear the composer after sending. When send is set to false, determines if composer text is replaced with suggestion (true, default), or if the suggestion's prompt is appended to the composer text (false).
autoSend?:
Deprecated. Use 'send' instead.
method?:
Deprecated. This parameter is no longer used.
asChild:
Merge props with child element instead of rendering a wrapper button.
className?:
CSS class name.
This primitive renders a <button>
element unless asChild
is set.
If
Conditionally renders children based on thread state.
ThreadPrimitiveIfProps
empty?:
Render children if the thread is empty (no messages).
running?:
Render children if the thread is running (assistant is responding).
disabled?:
Render children if the thread is disabled.
Multiple conditions can be combined on ThreadPrimitive.If
- all specified conditions must match for children to render.
Related Components
- ThreadList - List of threads, with or without sidebar