@onyx/ui
Shared shadcn/ui components on Base UI with Tailwind v4.
@onyx/ui is the shared component library: shadcn/ui components built on Base UI (the shadcn default) with Tailwind v4. Components are plain source files exported directly from the package, so apps import exactly the pieces they use and Tailwind scans the sources as part of the app build. The default typeface is Geist via Fontsource.
Exports
The export map exposes source files by path rather than a barrel:
| Import path | What it provides |
|---|---|
@onyx/ui/globals.css | The theme, design tokens, and Tailwind setup. Import once per app. |
@onyx/ui/components/* | The component library, one module per component. |
@onyx/ui/hooks/* | Shared hooks, for example use-mobile. |
@onyx/ui/lib/* | Utilities, for example cn() in lib/utils. |
Consuming components
Import each component from its own module. Typical usage in apps/web:
import { Button } from '@onyx/ui/components/button';
import { Card, CardContent, CardHeader, CardTitle } from '@onyx/ui/components/card';
import { Field, FieldError, FieldLabel } from '@onyx/ui/components/field';
import { Input } from '@onyx/ui/components/input';The library covers the usual primitives (button, card, dialog, dropdown-menu, select, sheet, sidebar, tooltip, and so on) plus components/ai-elements/*, the chat building blocks used by the AI assistant (conversation, message, prompt-input, tool, code-block, loader).
The cn() helper merges conditional class names with Tailwind-aware deduping. It is re-exported from the cnfast package (src/lib/utils.ts is just export { cn } from 'cnfast'), but keep importing it from @onyx/ui/lib/utils:
import { cn } from '@onyx/ui/lib/utils';
<div className={cn('flex items-center', className)} />;Styles and theming
Each app imports the stylesheet once. In apps/web/src/style.css:
@import '@onyx/ui/globals.css';globals.css imports Tailwind, tw-animate-css, the shadcn Tailwind layer, and the Geist font, then defines the theme:
- Design tokens are CSS variables on
:root(light) and.dark(dark), in oklch:--background,--foreground,--primary,--muted,--destructive,--border,--ring, the--sidebar-*family, and more. - An
@theme inlineblock maps them to Tailwind color utilities, sobg-background,text-muted-foreground, orborder-borderresolve to the tokens. - Radius scales derive from a single
--radiusvariable (--radius-smthrough--radius-4xl). - Dark mode is a class:
@custom-variant dark (&:is(.dark *)), so toggling.darkon a root element switches the palette.
To rebrand, edit the token values in globals.css; components pick the changes up through the Tailwind utilities.
Adding components
Components are vendored source, not a dependency. Add new ones by copying from the shadcn base registry variant (the Base UI builds) into private/ui/src/components/. The package's components.json configures the shadcn CLI for this layout, including the @basecn registry (https://basecn.dev/r/{name}.json), so from private/ui you can run:
npx shadcn@latest add @basecn/<component>After adding a file under src/components/, it is immediately importable as @onyx/ui/components/<name> through the wildcard export. Adjust imports inside the copied file to the package aliases if needed (@/lib/utils maps to src/lib/utils).