Quick start

Install the package, set it up, and assemble your first chat.

@intentface/chat ships the behavior of a chat interface and none of its appearance. This page takes you from an empty React 19 app to a working chat.

Install the library

npm install @intentface/chat

react and react-dom (v19+) are the only peer dependencies. Nothing else ships with it beyond two small runtime deps — @floating-ui/dom for anchored positioning and nanoid for attachment ids. No styling, no editor framework, no animation library.

Each primitive is a separate entry point:

import { Composer } from "@intentface/chat/composer";
import { Message } from "@intentface/chat/message";
import { Thread } from "@intentface/chat/thread";
import { groupTurns } from "@intentface/chat/message-utils";

Set up

Portals

The composer's command popover, its panel, and the attachment preview all render through portals into document.body, so they escape any overflow or transform on your layout. To keep them above the rest of the page regardless of your own stacking, give your app root its own stacking context.

In your root layout:

<body>
  <div className="root">{children}</div>
</body>

And in your global stylesheet:

.root {
  isolation: isolate;
}

Without this, a z-index anywhere in your layout can paint over the command popover.

Assemble a component

Three primitives make a chat: Thread owns the scroll area and reserves space for its docked composer, Message renders each turn, and Composer takes input. Every part renders semantic DOM with data-* state attributes and no classes of its own — you pass className to each one, so the look is yours from the first render.

Can you summarise this thread?
Sure — it covers the composer's segment model, how chips serialise, and why the editor owns its own DOM.

Composer.Submit disables itself while the field is empty, and Thread publishes its docked-composer reserve as --thread-overlay-bottom-height so the scroll area never hides behind it. See Composer, Thread, and Message for the full part lists.

Pre-styled components

There is no pre-styled @intentface/chat package, and no CSS to install. The demos on each component page are the styled reference: they use stock Tailwind, depend on nothing but this package, and are meant to be copied and edited.

This site's own chat is built from components that live in the app, not the package. They use design tokens, Motion, and local icon files, and they are not published — read them as a reference implementation if you like, but they are not a starting point.

Working with LLMs

Append .md to any docs URL to get that page as markdown — for example /primitives/composer.md. Every demo's source is inlined into it as a code block, so an agent reading the page gets the code rather than a component tag it can't resolve. The View as Markdown link in the page header does the same thing.

/llms.txt indexes every page with its description and markdown URL. Feed it to an assistant to let it navigate the docs without crawling HTML.

Next steps

  • Styling — the state model, data attributes, and render props
  • Composer — commands, chips, attachments, and the ask-user flow
  • Thread — the scroll container and auto-follow behavior