Crafted, copy-paste interface primitives for AI-native products — thinking and reasoning states, streaming answers, human-in-the-loop approvals, tool-call and task status, records and diff tables, prompt bars, and more — plus a live harness that arranges them into a working agent chat.
Everything is one self-contained component per primitive, built on a small design-token layer. MIT licensed. Take it, wire it to your own agent, ship it.
- Gallery: every primitive as a live, copy-paste demo —
/ - Harness: the primitives composed into an agent chat —
/harness
git clone https://github.com/slev12397/beautiful-ui.git
cd beautiful-ui
npm install
npm run devOpen http://localhost:3000. Analytics and email capture are optional (see Environment) — but note the icon set below is not.
Heads up — commercial icon set.
SidebarNavuses@central-icons-react, a paid icon library with a license check that runs onnpm install. SetCENTRAL_LICENSE_KEYin your environment before installing, or swap those imports incomponents/primitives/SidebarNav.tsxfor your own icons. Everything else runs with no configuration.
Stack: Next.js (App Router) · React · Tailwind CSS v4 · TypeScript.
app/
globals.css design tokens (:root, .dark, @theme) + component CSS
layout.tsx fonts (Inter + JetBrains Mono), theme boot
page.tsx the gallery
harness/page.tsx the harness route
components/
primitives/* the library — one self-contained file per primitive
site/* the shell/chrome (harness, gallery grid, theme, sounds)
lib/
meta.ts, registry.tsx the gallery catalog
The primitives are the product. Most files under components/primitives/ paste
in on their own; some also import a shared building block (Button, GlideMenu,
EntityChip, …) or an npm package (liveline, glimm, iconoir-react, …). Every
component's exact dependencies are listed on its gallery card, and the
component registry resolves them for you automatically.
Recommended — the CLI resolves the whole dependency tree (internal building blocks, npm packages, and only the CSS a component actually needs):
npx shadcn add https://www.beautifului.dev/r/approval-card.jsonBrowse the index at
/r/registry.json. Each item
declares its registryDependencies, npm dependencies, and files, so one
add pulls the component, its building blocks, installs its packages, and drops
in the foundation plus any component-specific CSS (e.g. records-table.css) —
not the whole stylesheet.
Manual — copy-paste: open a component's code view in the gallery; it lists
exactly what to also copy and npm i. Add the foundation
once, then paste the component and anything under "Requires".
Tokens live in app/globals.css as Tailwind v4 @theme variables, themed for
light and dark from the same source:
- Cool, blue-tinted neutrals, solid hairline borders (not alpha), one blue accent, semantic color (green/orange/red) used sparingly.
- Tight radii — chip
6· control8· card10· window14· pill. - Restrained, layered shadows — hairline · btn · card · raised · overlay.
- Type — Inter (tight tracking, tabular numerals) + JetBrains Mono.
A single component is not self-contained on its own — it renders on this
shared foundation stylesheet. Before pasting any primitive, drop
app/globals.css
into your project in full, once. It contains everything the components rely on:
@import "tailwindcss"and@import "shadow-plugin/unprefixed"(the smooth--shadow-xs … --shadow-lgscale thatshadow-card/shadow-overlaybuild on)- the
:root/.darkvariables and the@theme inlineblock that maps them to the utilities (bg-ink,text-ink-3,shadow-overlay,rounded-window, …) - every
@keyframes(pop-in,fade-up,shimmer-text,pixel-on,stream-in, …) and theprefers-reduced-motionfallbacks
The :root/.dark variables alone won't work — the @theme inline block is
what makes those utility classes exist. It's framework-agnostic: the same file
works in Vue, Svelte, or plain HTML on Tailwind v4.
components/site/IceCreamHarness.tsx is a demo: a SCENARIOS map turns fake
prompts into scripted replies built from the primitives. To make it real,
replace the demo data with your backend — the primitives stay exactly as they
are; they're just the rendering layer for your agent's output.
| Demo seam | Replace with |
|---|---|
SCENARIOS / matchScenario in IceCreamHarness.tsx |
your agent request per user message |
StreamingText / StreamLine |
your token stream (SSE or the AI SDK streamText) |
ThinkingState |
your agent's reasoning / step events |
ToolChips |
your tool-call events and their results |
ApprovalCard |
your human-in-the-loop confirmations |
ContextCards |
your retrieval / memory chunks |
RecordsTable / DiffTable |
your data and proposed edits |
model picker in PromptBar |
your available models |
A typical production wiring:
- Models — call your LLM from a Next.js route or Server Action. On Vercel,
the AI SDK + AI Gateway lets you use
"provider/model"strings and stream tokens straight intoStreamingText. - Streaming — stream tokens (SSE /
ReadableStream) into the streaming primitives; they render word-by-word as data arrives. - Tools & approvals — map your agent's tool-call and confirmation events
onto
ToolChips,ThinkingState, andApprovalCard. - Memory & context — feed your retrieval/memory results into
ContextCardsand the side pane; persist threads however you like (the harness keeps them in local state for the demo). - Data — point
RecordsTable/DiffTableat your real rows.
All optional. Copy .env.example to .env.local to enable them.
| Variable | Purpose |
|---|---|
NEXT_PUBLIC_POSTHOG_PROJECT_TOKEN |
PostHog analytics (client) |
NEXT_PUBLIC_POSTHOG_HOST |
PostHog host |
RESEND_API_KEY |
email capture via Resend (server-only) |
Without them, analytics is disabled and the email-capture endpoint returns a graceful "unavailable" — nothing crashes.