React components and chat layouts for OpenUI. Use the ready-made chat surfaces, the built-in model-renderable component library, or the individual UI primitives in your own layout.
Links: Package docs | Chat docs | GitHub repo
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";This package provides three layers:
- Chat layouts for full-screen chat, copilots, and bottom-tray experiences.
- Model-renderable components for charts, tables, forms, cards, and other OpenUI Lang output.
- Standalone UI primitives such as
Button,Card,Table,Charts, and the chat shell pieces.
The fastest way to get a working chat app:
import { FullScreen } from "@openuidev/react-ui";
import "@openuidev/react-ui/styles/index.css";
function App() {
return <FullScreen apiUrl="/api/chat" threadApiUrl="/api/threads" />;
}| Component | Description |
|---|---|
FullScreen |
Full-page chat with a thread sidebar |
Copilot |
Side-panel copilot overlay |
BottomTray |
Collapsible bottom tray chat |
All chat layouts accept apiUrl, threadApiUrl, and theming props. See the chat docs for full configuration.
import { Copilot } from "@openuidev/react-ui";
function App() {
return (
<div>
<main>Your app content</main>
<Copilot apiUrl="/api/chat" threadApiUrl="/api/threads" />
</div>
);
}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);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 |
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;
}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.
- 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.
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.
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 | FullScreen, Copilot, BottomTray, Shell.*, CopilotShell.*, ToolCall, ToolResult |
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";| 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 |