@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.

ImportCascade behavior
@openuidev/react-ui/styles/index.cssDefault, unlayered styles. Override them with normal CSS specificity.
@openuidev/react-ui/layered/styles/index.cssThe 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-memory
    • llm: ChatLLM — required; { send({ threadId, messages, signal }), streamProtocol }
    • artifactRenderers?: ArtifactRendererConfig[]
    • artifactCategories?: ArtifactCategory[]
  • Shared UI props:
    • componentLibrary?: Library (from @openuidev/react-lang) — drives auto-GenUI rendering
    • components?: AgentInterfaceComponents{ AssistantMessage?, UserMessage? } overrides
    • logoUrl?: string
    • agentName?: string
    • labels?: AgentInterfaceLabels
    • starters?: ConversationStarterProps[]
    • starterVariant?: ConversationStarterVariant
    • scrollVariant?: ScrollVariant
    • scrollOnLoad?: boolean
  • Theme wrapper props:
    • theme?: ThemeProps
    • disableThemeProvider?: 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.

PropTypeDefaultDescription
countnumber1Number of bars to stack
heightstring"16px"Bar height
widthstring"100%"Bar width
borderRadiusstringundefinedBar border radius (defaults to --openui-radius-xs)

TableSkeleton

A table-shaped placeholder used by the genui Table component while queries load.

PropTypeDefaultDescription
rowsnumber5Number of skeleton rows
columnsnumber4Number of skeleton columns

Built-in genui components like Table automatically render TableSkeleton when useIsQueryLoading() is true and no data rows exist yet.

On this page