Introduction

An unstyled React primitive library for building AI chat interfaces.

@intentface/chat is an unstyled React library for building chat interfaces. It provides the behavior that chat UIs need and is hard to write — a rich-text composer, scroll ownership, message segmentation, streaming disclosure — and renders no styles of its own.

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 pointWhat it covers
/composerContenteditable editor, inline chips, prefix command lists, attachments, ask-user flow
/threadScroll container: at-bottom detection, auto-follow, dock measurement, prepend restoration
/messageMessage parts, turn grouping, chip-segmented text
/steps, /reasoningTool-call timelines and reasoning disclosure
/chip, /attachments, /ask-userThe remaining building blocks
/types, /message-utils, /chip-markdownThe message contract, part utilities, and the chip wire format

Next steps