# Primitives URL: /docs/ink/primitives Composable terminal components for building chat UIs with Ink. Primitives are thin wrappers around Ink components (`Box`, `Text`, `TextInput`) that integrate with the assistant-ui runtime. They accept all standard Ink props and add runtime-aware behavior. Primitives are exported directly from `@assistant-ui/react-ink` (e.g. `ThreadRoot`, `ComposerInput`), unlike the web package which uses namespace imports. Many primitives share their core logic with `@assistant-ui/react` via `@assistant-ui/core/react` — only the UI layer (Ink vs DOM) differs. Thread \[#thread] ```tsx import { ThreadRoot, ThreadMessages, ThreadEmpty, ThreadIf, } from "@assistant-ui/react-ink"; ``` ThreadRoot \[#threadroot] Container `Box` for the thread area. ```tsx {children} ``` | Prop | Type | Description | | --------- | ---------- | ---------------------- | | `...rest` | `BoxProps` | Standard Ink Box props | ThreadMessages \[#threadmessages] Renders the message list with automatic runtime integration. Each message is wrapped in a scoped context so that `useAuiState((s) => s.message)` works inside `renderMessage`. ```tsx } /> ``` | Prop | Type | Description | | --------------- | ------------------------------------------------------------------- | ---------------- | | `renderMessage` | `(info: { message: ThreadMessage; index: number }) => ReactElement` | Message renderer | ThreadEmpty \[#threadempty] Renders children only when the thread has no messages. ```tsx Send a message to get started ``` ThreadIf \[#threadif] Conditional rendering based on thread state. ```tsx No messages yet Generating... ``` | Prop | Type | Description | | --------- | --------- | ----------------------------- | | `empty` | `boolean` | Render when thread is empty | | `running` | `boolean` | Render when thread is running | ThreadSuggestion \[#threadsuggestion] Renders a suggestion button. Uses Ink `Box` + `Text`. ```tsx ``` | Prop | Type | Description | | ---------- | ----------------------- | ---------------------------------- | | `prompt` | `string` | The suggestion text | | `method` | `"replace" \| "append"` | How to insert the suggestion | | `autoSend` | `boolean` | Automatically send after inserting | Composer \[#composer] ```tsx import { ComposerRoot, ComposerInput, ComposerSend, ComposerCancel, ComposerAddAttachment, ComposerAttachments, ComposerIf, } from "@assistant-ui/react-ink"; ``` ComposerRoot \[#composerroot] Container `Box` for the composer area. ```tsx {children} ``` ComposerInput \[#composerinput] Ink `TextInput` wired to the composer runtime. Value is managed automatically. ```tsx ``` | Prop | Type | Description | | --------------- | --------- | ------------------------------------------------- | | `submitOnEnter` | `boolean` | Whether Enter sends the message (default: `true`) | | `placeholder` | `string` | Placeholder text when empty | | `autoFocus` | `boolean` | Auto-focus on mount | ComposerSend \[#composersend] `Box` that triggers sending the current message. Typically used with a button-like UI. ```tsx [Send] ``` ComposerCancel \[#composercancel] `Box` that cancels the current run. ```tsx [Stop] ``` ComposerAttachments \[#composerattachments] Renders composer attachments using the provided component configuration. ```tsx ``` | Prop | Type | Description | | ------------ | ------------------------------------------- | -------------------------------------- | | `components` | `{ Image?, Document?, File?, Attachment? }` | Component renderers by attachment type | ComposerAddAttachment \[#composeraddattachment] Triggers attachment addition. ```tsx [Attach] ``` ComposerIf \[#composerif] Conditional rendering based on composer state. Shared from `@assistant-ui/core/react`. ```tsx Currently editing ``` | Prop | Type | Description | | --------- | --------- | --------------------------------------- | | `editing` | `boolean` | Render when composer is in editing mode | Message \[#message] ```tsx import { MessageRoot, MessageContent, MessageIf, MessageParts, MessageAttachments, } from "@assistant-ui/react-ink"; ``` MessageRoot \[#messageroot] Container `Box` for a single message. ```tsx {children} ``` MessageContent \[#messagecontent] Renders message content parts. Tool call and data parts automatically render registered tool UIs (via `useAssistantTool` / `useAssistantDataUI`), falling back to render props if provided. ```tsx {part.text}} renderToolCall={({ part }) => [Tool: {part.toolName}]} /> ``` | Prop | Type | Description | | ----------------- | ------------------------------------------ | ----------------------- | | `renderText` | `(props: { part; index }) => ReactElement` | Text part renderer | | `renderToolCall` | `(props: { part; index }) => ReactElement` | Tool call fallback | | `renderImage` | `(props: { part; index }) => ReactElement` | Image part renderer | | `renderReasoning` | `(props: { part; index }) => ReactElement` | Reasoning part renderer | | `renderSource` | `(props: { part; index }) => ReactElement` | Source part renderer | | `renderFile` | `(props: { part; index }) => ReactElement` | File part renderer | | `renderData` | `(props: { part; index }) => ReactElement` | Data part fallback | MessageIf \[#messageif] Conditional rendering based on message properties. ```tsx You: Thinking... ``` | Prop | Type | Description | | ----------- | --------- | -------------------------------------- | | `user` | `boolean` | Render for user messages | | `assistant` | `boolean` | Render for assistant messages | | `running` | `boolean` | Render when message is being generated | | `last` | `boolean` | Render for the last message | MessageAttachments \[#messageattachments] Renders user message attachments using the provided component configuration. ```tsx [{attachment.name}], }} /> ``` | Prop | Type | Description | | ------------ | ------------------------------------------- | -------------------------------------- | | `components` | `{ Image?, Document?, File?, Attachment? }` | Component renderers by attachment type | Attachment \[#attachment] ```tsx import { AttachmentRoot, AttachmentName, AttachmentThumb, AttachmentRemove, } from "@assistant-ui/react-ink"; ``` Primitives for rendering individual attachments. AttachmentRoot \[#attachmentroot] Container `Box` for an attachment. AttachmentName \[#attachmentname] `Text` component displaying the attachment filename. AttachmentThumb \[#attachmentthumb] `Text` component displaying the file extension. AttachmentRemove \[#attachmentremove] Pressable that removes the attachment from the composer. ```tsx [x] ``` ActionBar \[#actionbar] ```tsx import { ActionBarCopy, ActionBarEdit, ActionBarReload, ActionBarFeedbackPositive, ActionBarFeedbackNegative, } from "@assistant-ui/react-ink"; ``` ActionBarCopy \[#actionbarcopy] Pressable that copies the message content. Supports function-as-children for copy state feedback. ```tsx {({ isCopied }) => {isCopied ? "[Copied!]" : "[Copy]"}} ``` | Prop | Type | Description | | ----------------- | ------------------------ | ----------------------------------------------------- | | `copiedDuration` | `number` | Duration in ms to show "copied" state (default: 3000) | | `copyToClipboard` | `(text: string) => void` | Custom clipboard function | ActionBarEdit \[#actionbaredit] Pressable that enters edit mode for a message. ```tsx [Edit] ``` ActionBarReload \[#actionbarreload] Pressable that regenerates an assistant message. ```tsx [Retry] ``` ActionBarFeedbackPositive / ActionBarFeedbackNegative \[#actionbarfeedbackpositive--actionbarfeedbacknegative] Pressable buttons for submitting message feedback. ```tsx {({ isSubmitted }) => {isSubmitted ? "[Liked]" : "[Like]"}} {({ isSubmitted }) => {isSubmitted ? "[Disliked]" : "[Dislike]"}} ``` BranchPicker \[#branchpicker] ```tsx import { BranchPickerPrevious, BranchPickerNext, BranchPickerNumber, BranchPickerCount, } from "@assistant-ui/react-ink"; ``` BranchPickerPrevious / BranchPickerNext \[#branchpickerprevious--branchpickernext] Pressable buttons to navigate between message branches. ```tsx {"<"} / {">"} ``` BranchPickerNumber / BranchPickerCount \[#branchpickernumber--branchpickercount] `Text` components displaying the current branch number and total count. ThreadList \[#threadlist] ```tsx import { ThreadListRoot, ThreadListItems, ThreadListNew, } from "@assistant-ui/react-ink"; ``` ThreadListRoot \[#threadlistroot] Container `Box` for the thread list. ThreadListItems \[#threadlistitems] Renders thread list items with runtime integration. ```tsx ( )} /> ``` | Prop | Type | Description | | ------------ | -------------------------------------------------------------- | -------------------- | | `renderItem` | `(props: { threadId: string; index: number }) => ReactElement` | Thread item renderer | ThreadListNew \[#threadlistnew] Pressable that creates a new thread. ```tsx [New Chat] ``` ThreadListItem \[#threadlistitem] ```tsx import { ThreadListItemRoot, ThreadListItemTrigger, ThreadListItemDelete, ThreadListItemArchive, ThreadListItemUnarchive, } from "@assistant-ui/react-ink"; ``` ThreadListItemRoot \[#threadlistitemroot] Container `Box` for a thread list item. ThreadListItemTrigger \[#threadlistitemtrigger] Pressable that switches to the thread. ThreadListItemDelete \[#threadlistitemdelete] Pressable that deletes the thread. ThreadListItemArchive / ThreadListItemUnarchive \[#threadlistitemarchive--threadlistitemunarchive] Pressable buttons that archive or unarchive the thread. ```tsx Chat #1 [x] ``` Suggestion \[#suggestion] ```tsx import { SuggestionTitle, SuggestionDescription, SuggestionTrigger, } from "@assistant-ui/react-ink"; ``` SuggestionTitle \[#suggestiontitle] `Text` component displaying the suggestion title. SuggestionDescription \[#suggestiondescription] `Text` component displaying the suggestion description. SuggestionTrigger \[#suggestiontrigger] Pressable that triggers the suggestion action. ```tsx ``` | Prop | Type | Description | | --------------- | --------- | --------------------------------------------------------------- | | `send` | `boolean` | When true, sends immediately; when false, inserts into composer | | `clearComposer` | `boolean` | Whether to clear/replace composer text (default: true) | ChainOfThought \[#chainofthought] ```tsx import { ChainOfThoughtRoot, ChainOfThoughtAccordionTrigger, } from "@assistant-ui/react-ink"; ``` ChainOfThoughtRoot \[#chainofthoughtroot] Container `Box` for chain of thought content. ChainOfThoughtAccordionTrigger \[#chainofthoughtaccordiontrigger] Pressable that toggles the collapsed state of the chain of thought. ```tsx [Toggle reasoning] {/* reasoning content */} ``` ToolFallback \[#toolfallback] ```tsx import { ToolFallback } from "@assistant-ui/react-ink"; ``` A built-in component for rendering tool calls with expandable/collapsible output. Includes spinner for running tools and formatted JSON output. ```tsx } /> ```