React UI
React UI
Build Anvia chat, completion, tool-call, and human-input interfaces with composable React primitives.
React UI is the Anvia package for building application-owned AI interfaces. It sits on top of
@anvia/react: the hook package owns stream transport and state reduction, while
@anvia/react-ui owns composable components, contexts, and behavior.
Use it when you want ChatGPT-style chat surfaces, completion forms, tool call renderers, approval controls, and question flows without giving up control of markup and styling.
Prerequisites
React UI assumes three pieces are already in place:
- A React frontend application.
- An API application route that returns Anvia stream events.
- A
useChat(...)oruseCompletion(...)controller from@anvia/react.
The browser should not call provider SDKs or hold provider credentials. The browser sends messages to your API app, and your API app runs the model, agent, tools, auth checks, and persistence.
The beginner docs use http://localhost:5173 for the frontend and http://localhost:8787 for the
API app. In production, point the hook endpoint at your deployed API origin.
Chat vs completion
React UI has two separate surface families:
| Surface | Use when | Controller and provider | UI primitives |
|---|---|---|---|
| Chat | The user expects a transcript, follow-up turns, tools, attachments, selection quotes, thread history, or human review. | useChat(...) with ChatProvider |
Thread.*, Composer.*, Message.*, Image.*, SelectionToolbar.*, HumanInput.* |
| Completion | The user submits one prompt and reads one generated text result. | useCompletion(...) with CompletionProvider |
Completion.* |
Both families can call an API route that accepts { messages, stream: true }, but they expose
different client state and contexts. Do not mix Thread, Composer, Message, or HumanInput
inside CompletionProvider; use the chat family when those primitives are needed.
What to build first
Most applications start with a chat surface:
- Read the mental model for the provider and compound-component structure.
- Keep the cheat sheet open while composing the first surface.
- Build an API route that accepts
{ messages, stream: true }. - Create a
useChat(...)controller that points at that route. - Wrap the UI in
ChatProvider. - Render
Thread.Root,Thread.Viewport,Thread.Messages, andComposer.Root. - Keep the default message renderer until a part needs product-specific UI.
- Add custom Markdown, attachment, tool-card, and human-input rendering one piece at a time.
- Move layout, colors, spacing, and cards into application CSS or Tailwind classes.
The primitives give you state, accessibility-friendly defaults, and stable attributes. They do not try to own your design system.
Package boundary
@anvia/react-ui is headless. It provides primitives such as Thread, Composer, Message,
Image, SelectionToolbar, ThreadList, HumanInput, and Completion, plus stable
data-anvia-* attributes and an optional stylesheet.
Application code still owns:
- The API route and model selection.
- Auth, persistence, and tenancy.
- Final visual design and design-system integration.
- Custom rendering for domain-specific tool calls.
Beginner path
- Mental model: understand providers, compound components, and renderer levels.
- Cheat sheet: grab imports, skeletons, renderer rules, and common snippets.
- TanStack quickstart: build the frontend app and API app first.
- Server routes: understand the route contract.
- Request shape: add model selectors and metadata safely.
- Chat and composer: learn the thread and prompt primitives.
- Composer triggers: add mentions, slash commands, and variables.
- Messages: customize message rows and parts.
- Lifecycle and state: handle stop, errors, reset, and retry.
Example surfaces
- Full chat surface
- Composer attachments
- Composer triggers
- Message rendering
- Images, selection, and thread list
- Tool and human input
- Styling recipe
- Completion panel
- Tools end to end
- Human review end to end
- Attachments end to end
