Thread primitives for rendering chat transcripts, message lists, viewport state, suggestions, and composers in assistant-ui.
For examples and usage patterns, see Thread.
Anatomy
import { ThreadPrimitive } from "@assistant-ui/react";
const Thread = () => (
<ThreadPrimitive.Root>
<ThreadPrimitive.Viewport>
<AuiIf condition={(s) => s.thread.isEmpty}>...</AuiIf>
<ThreadPrimitive.Messages>{...}</ThreadPrimitive.Messages>
<ThreadPrimitive.ViewportFooter className="sticky bottom-0">
<Composer />
</ThreadPrimitive.ViewportFooter>
</ThreadPrimitive.Viewport>
</ThreadPrimitive.Root>
);API Reference
Root
The root container component for a thread. This component serves as the foundational wrapper for all thread-related components. It provides the basic structure and context needed for thread functionality.This primitive renders a <div> element unless asChild is set.
ThreadPrimitiveRootPropsasChild: boolean= falseChange the default rendered element for the one passed as a child, merging their props and behavior.
Read the Composition guide for more details.render?: ReactElement
Empty
If
ThreadPrimitiveIfPropsrunning?: booleandisabled?: booleanempty?: boolean
Viewport
A scrollable viewport container for thread messages. This component provides a scrollable area for displaying thread messages with automatic scrolling capabilities. It manages the viewport state and provides context for child components to access viewport-related functionality.This primitive renders a <div> element unless asChild is set.
ThreadPrimitiveViewportPropsasChild: boolean= falseChange the default rendered element for the one passed as a child, merging their props and behavior.
Read the Composition guide for more details.render?: ReactElementautoScroll?: booleanWhether to automatically scroll to the bottom when new messages are added. When enabled, the viewport will automatically scroll to show the latest content. Default false if `turnAnchor` is "top", otherwise defaults to true.
turnAnchor?: "top" | "bottom"Controls scroll anchoring behavior for new messages. - "bottom" (default): Messages anchor at the bottom, classic chat behavior. - "top": New user messages anchor at the top of the viewport for a focused reading experience.
topAnchorMessageClamp: ThreadPrimitiveViewportProps["topAnchorMessageClamp"]= { tallerThan: "10em", visibleHeight: "6em" }Clamps tall user messages so the assistant response stays in view.
tallerThan: string= "10em"Clamp messages taller than this. Supports `px`, `em`, and `rem`.
visibleHeight: string= "6em"Visible portion of clamped messages. Supports `px`, `em`, and `rem`.
scrollToBottomOnRunStart?: booleanWhether to scroll to bottom when a new run starts. Defaults to true.
scrollToBottomOnInitialize?: booleanWhether to scroll to bottom when thread history is first loaded. Defaults to true.
scrollToBottomOnThreadSwitch?: booleanWhether to scroll to bottom when switching to a different thread. Defaults to true.
ViewportProvider
ThreadPrimitiveViewportProviderPropsoptions?: ThreadViewportStoreOptionsturnAnchor?: "top" | "bottom"topAnchorMessageClamp?: ThreadViewportStoreOptions["topAnchorMessageClamp"]tallerThan?: stringvisibleHeight?: string
ViewportFooter
A footer container that measures its height for scroll calculations. This component measures its height and provides it to the viewport context so the auto-scroll system can account for any sticky footer overlapping the message list. Multiple ViewportFooter components can be used - their heights are summed. Typically used with `className="sticky bottom-0"` to keep the footer visible at the bottom of the viewport while scrolling.This primitive renders a <div> element unless asChild is set.
ThreadPrimitiveViewportFooterPropsasChild: boolean= falseChange the default rendered element for the one passed as a child, merging their props and behavior.
Read the Composition guide for more details.render?: ReactElement
Messages
ThreadPrimitiveMessagesPropscomponentsdeprecated?: MessagesComponentConfigDeprecated: Use the children render function instead.
Message?: ComponentTypeComponent used to render all message types
EditComposer?: ComponentTypeComponent used when editing any message type
UserEditComposer?: ComponentTypeComponent used when editing user messages specifically
AssistantEditComposer?: ComponentTypeComponent used when editing assistant messages specifically
SystemEditComposer?: ComponentTypeComponent used when editing system messages specifically
UserMessage?: ComponentTypeComponent used to render user messages specifically
AssistantMessage?: ComponentTypeComponent used to render assistant messages specifically
SystemMessage?: ComponentTypeComponent used to render system messages specifically
children?: (value: { message: MessageState }) => ReactNodeRender function called for each message. Receives the message.
MessageByIndex
Renders a single message at the specified index in the current thread.ThreadPrimitiveMessageByIndexPropsindex: numbercomponents: MessagesComponentConfigMessage?: ComponentTypeComponent used to render all message types
EditComposer?: ComponentTypeComponent used when editing any message type
UserEditComposer?: ComponentTypeComponent used when editing user messages specifically
AssistantEditComposer?: ComponentTypeComponent used when editing assistant messages specifically
SystemEditComposer?: ComponentTypeComponent used when editing system messages specifically
UserMessage?: ComponentTypeComponent used to render user messages specifically
AssistantMessage?: ComponentTypeComponent used to render assistant messages specifically
SystemMessage?: ComponentTypeComponent used to render system messages specifically
ScrollToBottom
This primitive renders a <button> element unless asChild is set.
ThreadPrimitiveScrollToBottomPropsasChild: boolean= falseChange the default rendered element for the one passed as a child, merging their props and behavior.
Read the Composition guide for more details.render?: ReactElementbehavior?: ScrollBehavior
Suggestion
This primitive renders a <button> element unless asChild is set.
ThreadPrimitiveSuggestionPropsasChild: boolean= falseChange the default rendered element for the one passed as a child, merging their props and behavior.
Read the Composition guide for more details.render?: ReactElementprompt: stringThe suggestion prompt.
send?: booleanWhen true, automatically sends the message. When false, replaces or appends the composer text with the suggestion - depending on the value of `clearComposer`.
clearComposer: boolean= trueWhether to clear the composer after sending. When send is set to false, determines if composer text is replaced with suggestion (true, default), or if it's appended to the composer text (false).
autoSenddeprecated?: booleanDeprecated: Use `send` instead.
methoddeprecated?: "replace"Deprecated: Use `clearComposer` instead.
Suggestions
ThreadPrimitiveSuggestionsPropscomponentsdeprecated?: SuggestionsComponentConfigDeprecated: Use the children render function instead.
Suggestion: ComponentTypeComponent used to render each suggestion
children?: (value: { suggestion: SuggestionState }) => ReactNodeRender function called for each suggestion. Receives the suggestion.
SuggestionByIndex
Renders a single suggestion at the specified index.ThreadPrimitiveSuggestionByIndexPropsindex: numbercomponents: SuggestionsComponentConfigSuggestion: ComponentTypeComponent used to render each suggestion