Introduction
An unstyled React primitive library for AI chat interfaces and the app shells around them.
@intentface/ui is an unstyled React library for AI chat interfaces and the app
shells around them. It provides the behavior that is hard to write and renders
no styles of its own. For the chat, that means a rich-text composer, scroll
ownership, message segmentation and streaming disclosure. For the shell around
it, that means a resizable sidebar, a nav tree and closable tabs.
React and React DOM are the only peer dependencies. There is no editor framework underneath, no animation library, and no opinion about transport: the package never makes a request.
Features
Headless
The primitives are unstyled, bundle no CSS, and prescribe no styling solution.
They render semantic DOM with data-* state attributes, and every part accepts
className, style, and a render prop. See Styling.
Composable
Each primitive is a namespace of parts you assemble yourself — Composer.Root,
Composer.Container, Message.Root. Parts can be reordered, omitted, or wrapped,
and every one exposes its state through context hooks.
Built for streaming
The composer's editor is isolated from the message stream, so tokens arriving dozens of times a second don't re-render it. The thread follows new content while you're at the bottom and releases when you scroll away. See Composer performance.
AI SDK compatible
The package defines its own structural message types, which a Vercel AI SDK
UIMessage already satisfies — so SDK messages pass straight into the components
with no adapter.
Primitives
| Entry point | What it covers |
|---|---|
/composer | Contenteditable editor, inline chips, prefix command lists, attachments, ask-user flow |
/thread | Scroll container: at-bottom detection, auto-follow, dock measurement, prepend restoration |
/message | Message parts, turn grouping, chip-segmented text |
/steps | Collapsible timeline of a run: reasoning, tool calls and answered questions |
/reasoning | Reasoning disclosure that tracks streaming state and elapsed time |
/chip | Inline tokens for composer mentions and chips in messages |
/attachments | Attachment tray: items, remove, drop zone and file picker |
/ask-user | Parts for the questions a model asks the user |
/shell | Collapsible, resizable sidebar beside the viewport |
/nav | Nav tree with roving focus, typeahead and collapsible groups |
/tabs | Closable tabs whose panel renders in the layout or in a popover |
/types | The structural message contract |
/message-utils | Pure helpers over messages: part segments, turn grouping, text and file info |
/chip-markdown | Encode and parse the chip wire format inside message text |
Next steps
- Quick start — install the package and assemble a chat
- Build a chat — the same result in four stages
- Accessibility — what the primitives wire up, and what you supply