MUI X
ChatCompose a complete chat UI from the headless namespaces while keeping styling decisions in your own code.
FeedbackBundle sizeFigmaSketchStarter threadSmallest complete shell9:04 AMStarter threadSmallest complete shellMUI GuideThis shell is intentionally small so the primitive boundaries stay obvious.YouShow me the smallest headless chat surface.SentSendThe canonical headless shell combines a provider-backed root, a pane layout, a conversation rail, a thread view, a message list, and a composer.
import {
Chat,
Composer,
ConversationList,
MessageGroup,
MessageList,
Conversation,
} from '@mui/x-chat/headless';
function ChatSurface(props: ChatRootProps) {
return (
Chat.Root {...props}>
Chat.Layout>
ConversationList.Root />
Conversation.Root>
Conversation.Header>
Conversation.Title />
Conversation.Subtitle />
Conversation.HeaderActions />
Conversation.Header>
MessageList.Root
renderItem={({ id, index }) => (
MessageGroup index={index} messageId={id} />
)}
/>
Composer.Root>
Composer.TextArea />
Composer.Toolbar>
Composer.AttachButton />
Composer.SendButton />
Composer.Toolbar>
Composer.Root>
Conversation.Root>
Chat.Layout>
Chat.Root>
);
}
CopyCopied(or $keyC)
Recommended reading orderComposition is the best entry point when you are starting from a blank screen. It shows how the primitive groups fit together before you drill into individual pages such as Layout, Messages, or Composer.
What composition gives you structural defaults for the main chat regions active-conversation wiring between the conversation list and thread message list semantics and list-management behavior grouped message composition without custom row bookkeeping a form-based conversation input with submission and attachment plumbing Chat.Root versus ChatProviderChat.Root is the headless entry point for pages that want both provider setup and UI structure in one place. It accepts the same runtime props as the headless provider, then renders your structural surface through a root slot.
Choose Chat.Root when you want:
a single component to own the runtime boundary headless primitives everywhere below the root slot replacement on the outer shellChoose ChatProvider directly when only part of the tree should use headless primitives or when a page mixes several rendering approaches.
Namespace usageThe namespaced exports are useful when you want the API to read like a component family:
Chat.Root and Chat.Layout ConversationList.Root, ConversationList.Item, ConversationList.ItemAvatar, ConversationList.Title, ConversationList.Preview, ConversationList.Timestamp, and ConversationList.UnreadBadge Conversation.Root, Conversation.Header, Conversation.Title, Conversation.Subtitle, and Conversation.HeaderActions MessageList.Root and MessageList.DateDivider Message.Root, Message.Avatar, Message.Content, Message.Meta, and Message.Actions Composer.Root, Composer.TextArea, Composer.Toolbar, Composer.AttachButton, Composer.HelperText, and Composer.SendButton Indicators.TypingIndicator, Indicators.UnreadMarker, and Indicators.ScrollToBottomAffordanceDirect imports are useful when a codebase prefers explicit component names or tree-local imports.
Common composition variationsThe canonical shell is not the only valid headless layout.
Focused threadUse only the thread pane when a page already chooses the active conversation elsewhere:
Chat.Root {...props}>
Chat.Layout>
Conversation.Root>
Conversation.Header>
Conversation.Title />
Conversation.Subtitle />
Conversation.Header>
MessageList.Root
renderItem={({ id, index }) => MessageGroup index={index} messageId={id} />}
/>
Composer.Root>
Composer.TextArea />
Composer.SendButton />
Composer.Root>
Conversation.Root>
Chat.Layout>
Chat.Root>
CopyCopied(or $keyC)
Custom row pipelineWhen a thread needs unread markers, date dividers, indicators, or custom message actions, keep those concerns inside renderItem so they stay aligned with message ordering:
MessageList.Root
renderItem={({ id, index }) => (
>
Indicators.UnreadMarker index={index} messageId={id} />
MessageList.DateDivider index={index} messageId={id} />
MessageGroup index={index} messageId={id} />
>
)}
/>
CopyCopied(or $keyC)
What headless owns
semantics and accessibility roles
structural composition defaults
focus and keyboard behavior
slot replacement and owner-state-driven customization
What headless does not own
transport and backend integration details
normalized store semantics and runtime contracts
a visual design system, theme, or polished default look
For runtime behavior, continue with Headless. For styling and theming patterns, continue with Customization. For concrete patterns, continue with Examples.
API ChatRoot ChatLayout APISee the documentation below for a complete reference to all of the props and classes available to the components mentioned here.
Edit this pageWas this page helpful?
•
Blog•
StoreContents
Recommended reading orderWhat composition gives youChat.Root versus ChatProviderNamespace usageCommon composition variationsFocused threadCustom row pipelineWhat headless ownsWhat headless does not ownAPIAPIBecome a Diamond sponsorMUI stands in solidarity with Ukraine.Chat - Headless composition - MUI X,AI智能索引,全网链接索引,智能导航,网页索引
- Compose a complete chat UI from the headless namespaces while keeping styling decisions in your own code.