UI primitives with clean ownership.
Wensity UI primitives are foundational React controls for forms, selection, feedback, navigation, and layout. They live under /primitives so search engines, users, and the command palette all resolve each primitive to one canonical detail route.
Use this guide when you want Button, Input, Toggle, Dialog, Breadcrumb, Table, or any other of the 56 primitives as source in your app. For composed product UI (Agentic AI, SaaS blocks, Show Off, and related categories), keep using the Components guide and /components.
What primitives are
Primitives are the small controls and layout pieces that larger Wensity components depend on.
A primitive installs as a local .tsx file through the same Wensity registry contract as components.
The public catalog is /primitives, and each detail page uses /primitives/<slug>.
After install, the primitive is application code. Your formatter, linter, and git diff own the change.
Canonical routes
Primitive detail pages should be linked as /primitives/<slug>. Do not link primitive details through /components/<slug>, because the primitive route owns the canonical metadata, Open Graph URL, sitemap entry, and structured data.
Use /primitives/button for the Button primitive, /primitives/input for the Input primitive, and /docs/primitives for the install workflow. Keep /components focused on composed product UI.
Install with CLI
Configure icons, radius, fonts, and control-solid colors once with the Create preset studio, then run the generated init --preset or apply --preset command. Or initialise with defaults:
$pnpm dlx wensity init
$pnpm dlx wensity add button
The CLI reads wensity.json, writes source into your configured components path, adds helper files when needed, rewrites internal imports to your aliases, applies stored primitive style (CSS + Tabler/Lucide), and installs declared package dependencies.
import { Button } from "@/components/wensity/button";export default function Page() {return (<main className="grid min-h-screen place-items-center"><Button>Continue</Button></main>);}
CLI vs shadcn
| Wensity CLI | Public shadcn registry (@wensity/*) | |
|---|---|---|
Stored presets (wensity.json style) | Yes | No |
| Lucide delivery | Yes, install-time transform | No, Tabler-canonical only |
| Full editable source | Yes | Yes |
@wensity/ui runtime | Never | Never |
| Base UI dependency | Ordinary local npm dep | Ordinary local npm dep |
Premium /components | Outside primitive presets | Not exported |
These are complementary paths, not feature parity. Prefer the Wensity CLI when you need presets or Lucide. Prefer shadcn when you already use shadcn registry tooling and only need a free Tabler primitive.
shadcn registry
Free primitives can also be installed through the public shadcn registry namespace.
$pnpm dlx shadcn@latest add @wensity/button
Use the Wensity CLI when you want the full Wensity config flow. Use shadcn when you already run a shadcn registry workflow and only need a quick free primitive add.
Manual source
The Code tab on each primitive detail page includes the install command, dependencies, full source, and usage snippet. Manual source is best for review. The CLI is better for repeatable team installs because it follows wensity.json and keeps helper paths consistent.
Theming
Primitives read the same Tailwind v4 tokens as Wensity components. Set the surface, border, foreground, muted foreground, and chili brand tokens once in your global CSS. Every primitive will inherit the same visual system.
Do not maintain a second primitive theme. Use the shared Wensity tokens from the Theming guide so Button, Input, Dialog, and larger components stay visually aligned.
Tokens & configuration
Installing a primitive writes two delimited blocks into your configured Tailwind CSS file: a Wensity Base Tokens block holding the semantic layer (--background, --foreground, --border, --muted*, --surface*) that the primitives paint with, and a Wensity Primitive Tokens block holding the --primitive-* namespace. shadcn installs receive the same values through cssVars / css on the registry item. Both blocks are replaced in place on re-run, and together they are the only configuration seam today: there is no runtime theme provider, settings UI, or per-primitive option graph.
| Role family | Examples | What it controls |
|---|---|---|
| Surfaces | --primitive-surface-elevated, --primitive-surface-overlay | Solid panel / popup fills (no gradients, no parchment) |
| Controls | --primitive-control-solid*, --primitive-control-height-* | Button/toggle fills and sm/md/lg heights |
| Status | --primitive-success, --primitive-warning, --primitive-info, --primitive-destructive* | Alert/toast/badge intents |
| Radius | --primitive-radius (+ derived control/surface/item) | One base radius; derived roles use max(0px, calc(...)) |
| Type | --primitive-font-sans, --primitive-font-display, --primitive-font-mono | Typography roles on primitives |
| Overlay | --primitive-shadow-*, --primitive-backdrop, z-scale notes | Modal / popover / toast stacking |
Future color, radius, font, or density presets only override these named variables in the delivered CSS block. Icon package selection is a CLI-time named-import transform for primitives, configure it with the Create preset studio.
Open-code contract: after wensity add <slug>, import from @/components/wensity/<slug> only. Installed files must not reference @wensity/ui. Behavioral packages such as @base-ui/react, framer-motion, gsap, ogl, and @tabler/icons-react (or lucide-react when selected) are normal npm dependencies in your app, not Wensity lock-in.
Slug note: text-area and empty-state are the canonical install slugs (kept for URL/CLI stability). Ecosystem aliases such as textarea / empty are a future option only, the CLI does not resolve aliases today.
When to use primitives
Choose primitives for base controls, form fields, overlays, navigation trails, tables, cards, and layout utilities.
Choose components for composed product UI with richer previews, multiple behaviors, and higher-level interaction patterns.
Choose blocks for full sections such as hero areas, navbars, footers, and marketing layouts.