@openuidev/react-ui
API reference for the AgentInterface chat surface and default component library exports.
Use this package for the prebuilt AgentInterface chat surface and default component library primitives.
Import
import { AgentInterface } from "@openuidev/react-ui";
import "@openuidev/react-ui/styles/index.css";Styling
Import one complete React UI stylesheet exactly once, normally from your application's global entry point.
| Import | Cascade behavior |
|---|---|
@openuidev/react-ui/styles/index.css | Default, unlayered styles. Override them with normal CSS specificity. |
@openuidev/react-ui/layered/styles/index.css | The same component styles wrapped in @layer openui for cascade-layered applications. |
Choose one variant. Do not import @openuidev/react-ui/components.css or the default styles/index.css alongside the layered stylesheet. The unlayered rules would take precedence over every named layer and defeat the intended ordering. Importing components.css with the default full stylesheet also duplicates the component rules in current releases.
For a single component, use @openuidev/react-ui/styles/<Component>.css or its layered counterpart at @openuidev/react-ui/layered/styles/<Component>.css instead of a full stylesheet.
Tailwind v4
Put the layer-order declaration and both imports at the top of the application's global stylesheet:
@layer theme, base, openui, components, utilities;
@import "tailwindcss";
@import "@openuidev/react-ui/layered/styles/index.css";This places Tailwind Preflight in base below OpenUI components, while Tailwind component and utility classes remain above OpenUI and can override it. The first layer-order declaration establishes precedence, so it must appear before other imports or rules that register those layers.
Keep the React UI import in one global entry point. Importing it again from a component or route can cause chunk-splitting bundlers to register openui before the intended global order, creating differences between development and production.
Put application-wide resets in a lower layer, normally base:
@layer base {
* {
box-sizing: border-box;
}
}An unlayered reset wins over every named layer regardless of selector specificity. The recipe above is specific to Tailwind v4; for Tailwind v3, preserve the same effective precedence using its directives and emitted CSS instead of copying the v4 imports.
The layered variant requires browser support for CSS cascade layers. Use the default unlayered stylesheet when supporting browsers that do not implement @layer.
Chat interface
AgentInterface is the package's chat surface — a full-page artifact chat with a thread-history sidebar, composer, and per-thread artifact workspace. It wraps ChatProvider, so it accepts the provider's storage + llm props alongside the shared UI props below.
AgentInterface
import { AgentInterface, openAIAdapter, type ChatLLM } from "@openuidev/react-ui";
import { openuiChatLibrary } from "@openuidev/react-ui/genui-lib";
const llm: ChatLLM = {
send: ({ messages, signal }) =>
fetch("/api/chat", { method: "POST", body: JSON.stringify({ messages }), signal }),
streamProtocol: openAIAdapter(),
};
<AgentInterface llm={llm} componentLibrary={openuiChatLibrary} />;Props (AgentInterfaceProps)
AgentInterface extends ChatProviderProps (minus children) and adds the shared UI + theme props:
- Chat provider props (from
@openuidev/react-headless):storage?: ChatStorage— thread (and optional artifact) persistence; defaults to in-memoryllm: ChatLLM— required;{ send({ threadId, messages, signal }), streamProtocol }artifactRenderers?: ArtifactRendererConfig[]artifactCategories?: ArtifactCategory[]
- Shared UI props:
componentLibrary?: Library(from@openuidev/react-lang) — drives auto-GenUI renderingcomponents?: AgentInterfaceComponents—{ AssistantMessage?, UserMessage? }overrideslogoUrl?: stringagentName?: stringlabels?: AgentInterfaceLabelsstarters?: ConversationStarterProps[]starterVariant?: ConversationStarterVariantscrollVariant?: ScrollVariantscrollOnLoad?: boolean
- Theme wrapper props:
theme?: ThemePropsdisableThemeProvider?: boolean
UI customization types
Types used by customization docs:
type AssistantMessageComponent = React.ComponentType<{ message: AssistantMessage }>;
type UserMessageComponent = React.ComponentType<{ message: UserMessage }>;
type ComposerProps = {
onSend: (message: string) => void;
onCancel: () => void;
isRunning: boolean;
isLoadingMessages: boolean;
};
type ComposerComponent = React.ComponentType<ComposerProps>;
type WelcomeMessageConfig =
| React.ComponentType<any>
| {
title?: string;
description?: string;
image?: { url: string } | React.ReactNode;
};
interface ConversationStartersConfig {
variant?: "short" | "long";
options: ConversationStarterProps[];
}Component library exports
Two ready-to-use libraries ship with @openuidev/react-ui. Import from the genui-lib subpath:
import {
// Chat-optimised (root = Card, includes FollowUpBlock, ListBlock, SectionBlock)
openuiChatLibrary,
openuiChatPromptOptions,
openuiChatExamples,
openuiChatAdditionalRules,
openuiChatComponentGroups,
// General-purpose (root = Stack, full component suite)
openuiLibrary,
openuiPromptOptions,
openuiExamples,
openuiAdditionalRules,
openuiComponentGroups,
} from "@openuidev/react-ui/genui-lib";openuiChatLibrary — Root is Card (vertical, no layout params). Includes chat-specific components: FollowUpBlock, ListBlock, SectionBlock. Does not include Stack. Use with the AgentInterface chat surface.
openuiLibrary — Root is Stack. Full layout suite with Stack, Tabs, Carousel, Accordion, Modal, etc. Use with the standalone Renderer or any non-chat layout (e.g., playground, embedded widgets, dashboards).
openuiPromptOptions — includes examples and additional rules for the general-purpose library. Does not include toolExamples — pass those in your app-level PromptSpec alongside tool descriptions.
Generate the system prompt at build time with the CLI:
pnpx @openuidev/cli@latest generate ./src/library.ts --out src/generated/system-prompt.txt// Chat interface — system prompt stays on the server
<AgentInterface componentLibrary={openuiChatLibrary} ... />
// Standalone renderer
<Renderer response={message} library={openuiLibrary} />Skeleton components
Skeleton and TableSkeleton are loading-state placeholders that render while data-driven genui components wait for Query() results. They use theme-aware CSS variables and a pulsing opacity animation.
import { Skeleton, TableSkeleton } from "@openuidev/react-ui";Skeleton
A generic skeleton bar. Use standalone or with count for stacked bars.
| Prop | Type | Default | Description |
|---|---|---|---|
count | number | 1 | Number of bars to stack |
height | string | "16px" | Bar height |
width | string | "100%" | Bar width |
borderRadius | string | undefined | Bar border radius (defaults to --openui-radius-xs) |
TableSkeleton
A table-shaped placeholder used by the genui Table component while queries load.
| Prop | Type | Default | Description |
|---|---|---|---|
rows | number | 5 | Number of skeleton rows |
columns | number | 4 | Number of skeleton columns |
Built-in genui components like Table automatically render TableSkeleton when useIsQueryLoading() is true and no data rows exist yet.