Getting started
Build a small React interface, then add the components you need. Unseen UI is an experimental alpha; APIs may change between releases.
1. Install from npm
The packages are public on npm under the alpha tag. Your app needs React and ReactDOM ^19.3.0, a bundler that supports CSS imports, and React types if you use TypeScript.
npm install @stackunseen/ui@alpha react@^19.3.0 react-dom@^19.3.0
@stackunseen/ui-core installs automatically as a dependency. Pin the exact version in your lockfile; the alpha tag moves with each prerelease.
Work from the source repository instead
The source repository is private. With an authorized checkout, use Node 24.13 or later within Node 24 and pnpm 11.5.0. From the repository root:
pnpm install --frozen-lockfile
pnpm build:packages
pnpm dev
Open the development site. Build the packages before starting a workspace consumer.
For the static website preview:
pnpm --filter @ai-interaction/docs build
node apps/docs/scripts/preview.mjs
Open the website preview. The preview serves the built site; rebuild the docs app after changing a page.
2. Render your first component
Import the base stylesheet once and wrap your interface in AITheme. In Next.js, this interactive example belongs in a Client Component; other React apps can use the same component.
This example keeps a draft and a saved name in memory. Nothing is sent or persisted. Copy it into a .tsx file and render <FirstExample /> from your app:
'use client';
import { useState } from 'react';
import { AITheme, Button, Field, Input } from '@stackunseen/ui';
import '@stackunseen/ui/styles.css';
export function FirstExample() {
const [name, setName] = useState('');
const [savedName, setSavedName] = useState('');
return (
<AITheme>
<form
style={{ display: 'grid', gap: 12, maxWidth: 360 }}
onSubmit={(event) => {
event.preventDefault();
setSavedName(name.trim());
}}
>
<Field label="Your name" required>
<Input
name="displayName"
value={name}
maxLength={80}
onChange={(event) => setName(event.target.value)}
/>
</Field>
<Button type="submit">Save locally</Button>
<p role="status">{savedName ? `Saved locally: ${savedName}` : 'Nothing saved yet.'}</p>
</form>
</AITheme>
);
}
The value and callback stay in your application. To save to a server, replace the local update with your host's validation and receipt handling. Read Connect to your app before wiring tools, approvals or execution.
3. Add only the entries you need
Ordinary controls come from @stackunseen/ui. DataGrid has a separate entry and stylesheet. Keep the base CSS and AITheme from the first example.
import { DataGrid } from '@stackunseen/ui/application';
import '@stackunseen/ui/application.css';
Open the DataGrid guide for controlled rows, sorting and paging. This entry needs no additional optional peers.
Other optional entries and their dependencies
The paths below are subpaths of @stackunseen/ui. Install optional peers only for entries you import. The base React and ReactDOM peers are still required. Exact supported ranges are in the React package manifest included with the local build.
| Entry | Additional peers | Extra CSS |
|---|---|---|
/theme, /status, /code | None | None |
/markdown | react-markdown, remark-gfm, remend | None |
/math | katex | katex/dist/katex.min.css |
/mermaid | mermaid, dompurify | KaTeX CSS for math labels |
/rich-markdown | Markdown peers, remark-math, katex, mermaid, dompurify | katex/dist/katex.min.css |
/highlight | shiki | None |
/terminal | @xterm/xterm, @xterm/addon-fit | @stackunseen/ui/terminal.css |
/viewport | @tanstack/react-virtual | None |
/layout | react-resizable-panels | None |
/sidecar, /workspace, /upload | None | None |
For example, a Markdown response needs these imports after installing its peers:
import { MarkdownResponse } from '@stackunseen/ui/markdown';
import '@stackunseen/ui/styles.css';
Follow each component's usage guide for its required values and callbacks. There are no /button or /icons subpaths.
4. Find your next step
- UI components: controls, layout and rich content.
- AI components: conversations, generated output, execution and review.
- SaaS admin example: a working app with customer records, members and settings.
Customize previews appearance, colors, density and corners. Themes and icons covers AITheme, IconsProvider and custom header/footer composition. For server responses and optional workflow examples, read Connect to your app.
Compound parts in Server Components
Compound components such as Card.Header, Sidebar.Group, Tooltip.Trigger and NavigationMenu.List are undefined when imported into a Next.js Server Component, because the client reference proxy does not carry static properties. Every part is also a top-level named export, so import those there:
import { Card, CardHeader, CardTitle, CardContent } from '@stackunseen/ui';
The property form (Card.Header) works in Client Components. Button, LinkButton, Tag, Stat, LinkCard, Card, Table, Breadcrumb and the marketing blocks render in Server Components; controls with local state, such as Select, Avatar and ToggleGroup, are Client Components and can be rendered from a Server Component.
Dark code panels on a light page
Nest a second AITheme with appearance="dark" around HighlightedCodeBlock (or any component) to render it dark inside a light page. The nested provider inherits the parent theme's colours and scopes its tokens to that subtree, and portals opened from inside it keep the same appearance.
<AITheme appearance="dark">
<HighlightedCodeBlock code={code} language="tsx" />
</AITheme>