Package Exports
- @openuidev/react-ui
- @openuidev/react-ui/Accordion
- @openuidev/react-ui/AgentInterface
- @openuidev/react-ui/AgentInterface/_shared
- @openuidev/react-ui/AgentInterface/_shared/detailed-view
- @openuidev/react-ui/AgentInterface/_shared/store
- @openuidev/react-ui/AgentInterface/_shared/tool-renderer
- @openuidev/react-ui/AgentInterface/_shared/types
- @openuidev/react-ui/AgentInterface/_shared/utils
- @openuidev/react-ui/AgentInterface/components
- @openuidev/react-ui/Button
- @openuidev/react-ui/Buttons
- @openuidev/react-ui/Calendar
- @openuidev/react-ui/Callout
- @openuidev/react-ui/Card
- @openuidev/react-ui/CardHeader
- @openuidev/react-ui/Carousel
- @openuidev/react-ui/Charts
- @openuidev/react-ui/Charts/AreaChart
- @openuidev/react-ui/Charts/AreaChart/types
- @openuidev/react-ui/Charts/AreaChartCondensed
- @openuidev/react-ui/Charts/BarChart
- @openuidev/react-ui/Charts/BarChart/types
- @openuidev/react-ui/Charts/BarChartCondensed
- @openuidev/react-ui/Charts/HorizontalBarChart
- @openuidev/react-ui/Charts/HorizontalBarChart/types
- @openuidev/react-ui/Charts/LineChart
- @openuidev/react-ui/Charts/LineChart/types
- @openuidev/react-ui/Charts/LineChartCondensed
- @openuidev/react-ui/Charts/MiniAreaChart
- @openuidev/react-ui/Charts/MiniAreaChart/types
- @openuidev/react-ui/Charts/MiniBarChart
- @openuidev/react-ui/Charts/MiniBarChart/types
- @openuidev/react-ui/Charts/MiniLineChart
- @openuidev/react-ui/Charts/MiniLineChart/types
- @openuidev/react-ui/Charts/PieChart
- @openuidev/react-ui/Charts/PieChart/types
- @openuidev/react-ui/Charts/RadarChart
- @openuidev/react-ui/Charts/RadarChart/types
- @openuidev/react-ui/Charts/RadarChart/utils
- @openuidev/react-ui/Charts/RadialChart
- @openuidev/react-ui/Charts/RadialChart/types
- @openuidev/react-ui/Charts/ScatterChart
- @openuidev/react-ui/Charts/ScatterChart/types
- @openuidev/react-ui/Charts/SingleStackedBarChart
- @openuidev/react-ui/Charts/SingleStackedBarChart/components
- @openuidev/react-ui/Charts/SingleStackedBarChart/types
- @openuidev/react-ui/Charts/constants
- @openuidev/react-ui/Charts/hooks
- @openuidev/react-ui/Charts/shared
- @openuidev/react-ui/Charts/shared/LineInBarShape
- @openuidev/react-ui/Charts/shared/PortalTooltip
- @openuidev/react-ui/Charts/shared/PortalTooltip/utils
- @openuidev/react-ui/Charts/shared/SVGXAxisTick
- @openuidev/react-ui/Charts/shared/ScrollButtonsHorizontal
- @openuidev/react-ui/Charts/shared/ScrollButtonsVertical
- @openuidev/react-ui/Charts/shared/SideBarTooltip
- @openuidev/react-ui/Charts/types
- @openuidev/react-ui/Charts/utils
- @openuidev/react-ui/CheckBoxGroup
- @openuidev/react-ui/CheckBoxItem
- @openuidev/react-ui/CodeBlock
- @openuidev/react-ui/DatePicker
- @openuidev/react-ui/FollowUpBlock
- @openuidev/react-ui/FollowUpItem
- @openuidev/react-ui/FormControl
- @openuidev/react-ui/FormControl/Hint
- @openuidev/react-ui/IconButton
- @openuidev/react-ui/Image
- @openuidev/react-ui/ImageBlock
- @openuidev/react-ui/ImageGallery
- @openuidev/react-ui/Input
- @openuidev/react-ui/Label
- @openuidev/react-ui/ListBlock
- @openuidev/react-ui/ListItem
- @openuidev/react-ui/MarkDownRenderer
- @openuidev/react-ui/MessageLoading
- @openuidev/react-ui/Modal
- @openuidev/react-ui/OpenUIChat
- @openuidev/react-ui/OpenUIChat/utils
- @openuidev/react-ui/RadioGroup
- @openuidev/react-ui/RadioItem
- @openuidev/react-ui/SectionBlock
- @openuidev/react-ui/Select
- @openuidev/react-ui/Separator
- @openuidev/react-ui/Skeleton
- @openuidev/react-ui/Slider
- @openuidev/react-ui/Steps
- @openuidev/react-ui/SwitchGroup
- @openuidev/react-ui/SwitchItem
- @openuidev/react-ui/Table
- @openuidev/react-ui/Tabs
- @openuidev/react-ui/Tag
- @openuidev/react-ui/TagBlock
- @openuidev/react-ui/TextArea
- @openuidev/react-ui/TextCallout
- @openuidev/react-ui/TextContent
- @openuidev/react-ui/ThemeProvider
- @openuidev/react-ui/ToggleGroup
- @openuidev/react-ui/ToggleItem
- @openuidev/react-ui/ToolCall
- @openuidev/react-ui/ToolResult
- @openuidev/react-ui/_shared
- @openuidev/react-ui/_shared/store
- @openuidev/react-ui/_shared/tool-renderer
- @openuidev/react-ui/_shared/types
- @openuidev/react-ui/_shared/utils
- @openuidev/react-ui/components.css
- @openuidev/react-ui/defaults.css
- @openuidev/react-ui/genui-lib
- @openuidev/react-ui/index.css
- @openuidev/react-ui/layered/styles/accordion.css
- @openuidev/react-ui/layered/styles/agentInterface.css
- @openuidev/react-ui/layered/styles/button.css
- @openuidev/react-ui/layered/styles/buttons.css
- @openuidev/react-ui/layered/styles/calendar.css
- @openuidev/react-ui/layered/styles/callout.css
- @openuidev/react-ui/layered/styles/card.css
- @openuidev/react-ui/layered/styles/cardHeader.css
- @openuidev/react-ui/layered/styles/carousel.css
- @openuidev/react-ui/layered/styles/charts.css
- @openuidev/react-ui/layered/styles/checkBoxGroup.css
- @openuidev/react-ui/layered/styles/checkBoxItem.css
- @openuidev/react-ui/layered/styles/codeBlock.css
- @openuidev/react-ui/layered/styles/datePicker.css
- @openuidev/react-ui/layered/styles/followUpBlock.css
- @openuidev/react-ui/layered/styles/followUpItem.css
- @openuidev/react-ui/layered/styles/formControl.css
- @openuidev/react-ui/layered/styles/iconButton.css
- @openuidev/react-ui/layered/styles/image.css
- @openuidev/react-ui/layered/styles/imageBlock.css
- @openuidev/react-ui/layered/styles/imageGallery.css
- @openuidev/react-ui/layered/styles/index.css
- @openuidev/react-ui/layered/styles/input.css
- @openuidev/react-ui/layered/styles/label.css
- @openuidev/react-ui/layered/styles/listBlock.css
- @openuidev/react-ui/layered/styles/listItem.css
- @openuidev/react-ui/layered/styles/markDownRenderer.css
- @openuidev/react-ui/layered/styles/messageLoading.css
- @openuidev/react-ui/layered/styles/openui-defaults.css
- @openuidev/react-ui/layered/styles/radioGroup.css
- @openuidev/react-ui/layered/styles/radioItem.css
- @openuidev/react-ui/layered/styles/sectionBlock.css
- @openuidev/react-ui/layered/styles/select.css
- @openuidev/react-ui/layered/styles/separator.css
- @openuidev/react-ui/layered/styles/shared.css
- @openuidev/react-ui/layered/styles/skeleton.css
- @openuidev/react-ui/layered/styles/slider.css
- @openuidev/react-ui/layered/styles/steps.css
- @openuidev/react-ui/layered/styles/switchGroup.css
- @openuidev/react-ui/layered/styles/switchItem.css
- @openuidev/react-ui/layered/styles/table.css
- @openuidev/react-ui/layered/styles/tabs.css
- @openuidev/react-ui/layered/styles/tag.css
- @openuidev/react-ui/layered/styles/tagBlock.css
- @openuidev/react-ui/layered/styles/textArea.css
- @openuidev/react-ui/layered/styles/textCallout.css
- @openuidev/react-ui/layered/styles/textContent.css
- @openuidev/react-ui/layered/styles/toggleGroup.css
- @openuidev/react-ui/layered/styles/toggleItem.css
- @openuidev/react-ui/layered/styles/toolCall.css
- @openuidev/react-ui/layered/styles/toolResult.css
- @openuidev/react-ui/scssUtils
- @openuidev/react-ui/styles/accordion.css
- @openuidev/react-ui/styles/agentInterface.css
- @openuidev/react-ui/styles/button.css
- @openuidev/react-ui/styles/buttons.css
- @openuidev/react-ui/styles/calendar.css
- @openuidev/react-ui/styles/callout.css
- @openuidev/react-ui/styles/card.css
- @openuidev/react-ui/styles/cardHeader.css
- @openuidev/react-ui/styles/carousel.css
- @openuidev/react-ui/styles/charts.css
- @openuidev/react-ui/styles/checkBoxGroup.css
- @openuidev/react-ui/styles/checkBoxItem.css
- @openuidev/react-ui/styles/codeBlock.css
- @openuidev/react-ui/styles/cssUtils.scss
- @openuidev/react-ui/styles/datePicker.css
- @openuidev/react-ui/styles/followUpBlock.css
- @openuidev/react-ui/styles/followUpItem.css
- @openuidev/react-ui/styles/formControl.css
- @openuidev/react-ui/styles/iconButton.css
- @openuidev/react-ui/styles/image.css
- @openuidev/react-ui/styles/imageBlock.css
- @openuidev/react-ui/styles/imageGallery.css
- @openuidev/react-ui/styles/index.css
- @openuidev/react-ui/styles/input.css
- @openuidev/react-ui/styles/label.css
- @openuidev/react-ui/styles/listBlock.css
- @openuidev/react-ui/styles/listItem.css
- @openuidev/react-ui/styles/markDownRenderer.css
- @openuidev/react-ui/styles/messageLoading.css
- @openuidev/react-ui/styles/openui-defaults.css
- @openuidev/react-ui/styles/radioGroup.css
- @openuidev/react-ui/styles/radioItem.css
- @openuidev/react-ui/styles/sectionBlock.css
- @openuidev/react-ui/styles/select.css
- @openuidev/react-ui/styles/separator.css
- @openuidev/react-ui/styles/shared.css
- @openuidev/react-ui/styles/skeleton.css
- @openuidev/react-ui/styles/slider.css
- @openuidev/react-ui/styles/steps.css
- @openuidev/react-ui/styles/switchGroup.css
- @openuidev/react-ui/styles/switchItem.css
- @openuidev/react-ui/styles/table.css
- @openuidev/react-ui/styles/tabs.css
- @openuidev/react-ui/styles/tag.css
- @openuidev/react-ui/styles/tagBlock.css
- @openuidev/react-ui/styles/textArea.css
- @openuidev/react-ui/styles/textCallout.css
- @openuidev/react-ui/styles/textContent.css
- @openuidev/react-ui/styles/toggleGroup.css
- @openuidev/react-ui/styles/toggleItem.css
- @openuidev/react-ui/styles/toolCall.css
- @openuidev/react-ui/styles/toolResult.css
Readme
@openuidev/react-ui
React components and a ready-made chat surface for OpenUI. Use the AgentInterface chat surface, the built-in model-renderable component library, or the individual UI primitives in your own layout.
Links: Package docs | Chat docs | GitHub repo
Install
npm install @openuidev/react-ui @openuidev/react-lang @openuidev/react-headless
# or
pnpm add @openuidev/react-ui @openuidev/react-lang @openuidev/react-headlessPeer dependencies: react >=19.0.0, react-dom >=19.0.0, zustand ^4.5.5, @openuidev/react-lang, @openuidev/react-headless
Don't forget to import the component styles:
import "@openuidev/react-ui/styles/index.css";Overview
This package provides three layers:
- A ready-made chat surface —
AgentInterface, a complete chat experience with thread history, streaming, and a model-renderable message area. - Model-renderable components for charts, tables, forms, cards, and other OpenUI Lang output.
- Standalone UI primitives such as
Button,Card,Table, andCharts.
Quick Start
The fastest way to get a working chat app is AgentInterface. Give it an llm transport that talks to your backend. Storage is optional — without it, threads live in memory and are wiped on reload:
import {
AgentInterface,
openAIAdapter,
openAIMessageFormat,
type ChatLLM,
} from "@openuidev/react-ui";
import { openuiChatLibrary } from "@openuidev/react-ui/genui-lib";
import "@openuidev/react-ui/styles/index.css";
const llm: ChatLLM = {
send: ({ messages, signal }) =>
fetch("/api/chat", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ messages: openAIMessageFormat.toApi(messages) }),
signal,
}),
streamProtocol: openAIAdapter(),
};
function App() {
return (
<AgentInterface
llm={llm}
componentLibrary={openuiChatLibrary}
agentName="My Assistant"
theme={{ mode: "light" }}
/>
);
}The chat surface
AgentInterface is the single chat surface. It adapts its layout responsively and accepts:
| Prop | Description |
|---|---|
storage |
Optional persistence adapter for thread history; defaults to in-memory (wiped on reload). Use restStorage from @openuidev/react-ui to back it with your own REST API |
llm |
Chat transport: { send({ messages, signal }), streamProtocol } |
componentLibrary |
OpenUI Lang library used to render assistant messages (e.g. openuiChatLibrary) |
theme |
Theme configuration, e.g. { mode: "light" } |
agentName |
Name displayed in the header |
starters |
Conversation-starter prompts shown on the welcome screen |
See the chat docs for full configuration.
Built-in Component Libraries
The package ships with two preconfigured OpenUI Lang libraries:
| Export | Description |
|---|---|
openuiLibrary |
Full component library for charts, tables, forms, cards, images, and more |
openuiChatLibrary |
Chat-optimized subset with follow-ups, steps, and callouts |
Use them directly when building custom chat experiences:
import { Renderer } from "@openuidev/react-lang";
import { openuiLibrary } from "@openuidev/react-ui";
function AssistantMessage({ content, isStreaming }) {
return <Renderer response={content} library={openuiLibrary} isStreaming={isStreaming} />;
}Generate a system prompt from the library:
import { openuiLibrary, openuiPromptOptions } from "@openuidev/react-ui";
const systemPrompt = openuiLibrary.prompt(openuiPromptOptions);Theming
Wrap your app in ThemeProvider to customize colors, typography, spacing, and effects:
import { ThemeProvider, createTheme } from "@openuidev/react-ui";
const customTheme = createTheme({
primary: "#6366f1",
background: "#fafafa",
foreground: "#1a1a1a",
});
function App() {
return (
<ThemeProvider mode="light" lightTheme={customTheme}>
<YourApp />
</ThemeProvider>
);
}| Export | Description |
|---|---|
ThemeProvider |
Context provider for theming |
createTheme(overrides) |
Create a theme with validation and defaults |
defaultLightTheme |
Built-in light theme |
defaultDarkTheme |
Built-in dark theme |
swatchTokens |
Token palette for use in theme builders |
Styling integration
OpenUI ships its component styles in two variants:
| Import | Cascade behavior |
|---|---|
@openuidev/react-ui/styles/index.css (default) |
Unlayered — override via normal CSS specificity, as in 0.11.x and earlier |
@openuidev/react-ui/layered/styles/index.css (opt-in) |
Wrapped in @layer openui — any unlayered consumer CSS wins |
Need a single component's CSS? Import it per component: ./styles/<Component>.css (unlayered) or ./layered/styles/<Component>.css (layered).
With the layered variant, plain CSS overrides OpenUI without !important or specificity matching:
@import "@openuidev/react-ui/layered/styles/index.css";
/* Wins, no specificity tricks needed */
.openui-button-base-primary {
background: hotpink;
}With Tailwind v4 (layered variant)
Declare layer order at the top of your entry stylesheet so openui sits above Tailwind's reset but below components and utilities:
@layer theme, base, openui, components, utilities;
@import "tailwindcss";
@import "@openuidev/react-ui/layered/styles/index.css";This places Tailwind's Preflight (in base) below OpenUI components so its element resets don't override them, while keeping utilities (bg-red-500, etc.) winning over OpenUI styles.
Rules for the layered variant
- Import OpenUI CSS from exactly one place — multiple import sites under chunk-splitting bundlers (e.g. Turbopack) can register
openuibefore your layer-order statement and lock the wrong order. - Wrap app-wide resets in a layer below
openui(e.g.@layer base { * { margin: 0; } }) — unlayered resets beat all layered styles regardless of specificity. ./defaults.cssand theThemeProviderruntime style injection stay unlayered in both modes so runtime theming always overrides component defaults.
Browser support
The layered variant requires CSS cascade layers: Chrome 99+, Firefox 97+, Safari 15.4+, Edge 99+ (all baseline from March 2022). On older browsers the @layer { ... } block is dropped entirely and components render unstyled. The default unlayered styles have no such floor.
Components
All components are available as individual imports:
| Category | Components |
|---|---|
| Layout | Card, CardHeader, SectionBlock, Tabs, Accordion, Carousel, Separator, Steps |
| Data Display | Table, Charts (bar, line, area, pie, radar, scatter), ListBlock, ListItem, Tag, TagBlock, CodeBlock, Image, ImageBlock, ImageGallery |
| Forms | Input, TextArea, Select, CheckBoxGroup, CheckBoxItem, RadioGroup, RadioItem, SwitchGroup, SwitchItem, Slider, DatePicker, FormControl, Label |
| Actions | Button, Buttons, IconButton, FollowUpBlock, FollowUpItem |
| Feedback | Callout, TextCallout, MessageLoading |
| Content | TextContent, MarkDownRenderer |
| Chat | AgentInterface, ToolCall, ToolResult |
Per-component imports
For smaller bundles, import components individually:
import { Button } from "@openuidev/react-ui/Button";
import { Card } from "@openuidev/react-ui/Card";
import { Charts } from "@openuidev/react-ui/Charts";Subpath Exports
| Import path | Description |
|---|---|
@openuidev/react-ui |
All components and libraries |
@openuidev/react-ui/styles/index.css |
Full compiled stylesheet, unlayered (default import) |
@openuidev/react-ui/layered/styles/index.css |
Full stylesheet wrapped in @layer openui (opt-in) |
@openuidev/react-ui/defaults.css |
Theme tokens, always unlayered |
@openuidev/react-ui/genui-lib |
OpenUI Lang libraries and prompt options |
@openuidev/react-ui/styles/* |
Per-component compiled styles (unlayered) |
@openuidev/react-ui/layered/styles/* |
Per-component styles wrapped in @layer openui |
@openuidev/react-ui/scssUtils |
SCSS utility functions |
@openuidev/react-ui/<Component> |
Per-component entry points |