name: shadcn-ui description: Build beautiful, accessible React UIs with shadcn/ui components. Use this skill whenever the user is building interfaces with React and shadcn/ui (or mentions shadcn, Radix-style components, or component libraries), when adding or customizing UI components like buttons, cards, dialogs, forms, tabs, dropdowns, or when theming or styling a React app that uses shadcn. Prefer this skill for concrete component usage, composition, and design tokens; combine with frontend-design for overall aesthetic direction.
Building Beautiful UI with shadcn/ui (React)
This skill guides you to build polished, accessible React interfaces using shadcn/ui: open-source, copy-paste components built on Radix UI and Tailwind CSS. shadcn is not an npm component library—components live in your repo and are fully editable. Use them as the building blocks for forms, layouts, overlays, and data display while keeping a consistent, themeable design.
When to Use This Skill
- The user wants to add or customize buttons, cards, inputs, dialogs, tabs, dropdowns, or other UI controls in a React app.
- The project already uses (or should use) shadcn/ui—check for
components.json,~/components/ui/*, orshadcninpackage.json. - The user asks about theming, dark mode, or design tokens (e.g.
--primary,--muted-foreground). - The user mentions "shadcn", "Radix", or "component library" in the context of React UI.
For overall visual direction (typography, color palettes, motion, layout philosophy), use the frontend-design skill in addition to this one. This skill focuses on how to implement with shadcn components and tokens.
Core Conventions
1. Project setup
- Config:
components.jsonat the project root defines style (new-yorkordefault), Tailwind CSS path, and aliases (e.g.~/components,~/lib/utils,~/components/ui). Respect these aliases in imports. - Utils: Components use
cn(...)from~/lib/utilsto merge class names (typicallyclsx+tailwind-merge). Always usecn(defaultClasses, className)so callers can override styles. - Slots: Many components use
data-slot="..."for styling hooks; avoid removing these when customizing.
2. Composition over configuration
Components are built from small, composable pieces. Prefer composing them rather than adding many props.
Example — Card:
Use Card, CardHeader, CardTitle, CardDescription, CardContent, CardFooter (and optionally CardAction) instead of a single “card” with a title prop.
<Card>
<CardHeader>
<CardTitle>Title</CardTitle>
<CardDescription>Optional description</CardDescription>
</CardHeader>
<CardContent>…</CardContent>
<CardFooter>…</CardFooter>
</Card>
Example — Form fields:
Use Label, Input, and wrapping divs (or the Field component if the project uses it) rather than a monolithic “form input” component.
3. Theming with CSS variables
shadcn themes via CSS variables in your global CSS (e.g. app.css or globals.css). Tailwind is wired to these via @theme inline (Tailwind v4) or theme config (v3).
- Semantic tokens: Use token-based classes so the UI respects light/dark and future theme changes:
- Surfaces:
bg-background,bg-card,bg-popover,bg-muted,bg-accent - Text:
text-foreground,text-muted-foreground,text-card-foreground - Actions:
bg-primary text-primary-foreground,bg-secondary text-secondary-foreground - Borders:
border-border,border-input - Destructive:
bg-destructive text-destructive-foreground
- Surfaces:
- Convention: For any semantic color there is usually a “foreground” counterpart (e.g.
--primaryand--primary-foreground) for text/icon on that background. Use the pair together for buttons and badges. - Radius: A single
--radiustoken drives--radius-sm,--radius-md,--radius-lg, etc. Userounded-md,rounded-lgso all corners stay consistent. - Adding new colors: Define variables under
:rootand.dark, then expose them to Tailwind via@theme inline { --color-<name>: var(--<name>); }so you can usebg-<name>andtext-<name>-foreground.
Avoid hardcoding hex/oklch in JSX; keep colors in CSS variables so theming and dark mode stay in one place.
4. Beautiful, consistent UI
- Spacing: Use the design system’s spacing (e.g.
gap-4,gap-6,p-6on cards) so layouts feel consistent. Avoid arbitrary values unless there’s a clear reason. - Hierarchy: Use
text-muted-foregroundfor secondary text, andfont-semiboldorfont-mediumfor headings so structure is clear. - Focus and accessibility: Components already include
focus-visible:ring-ring/50and similar. Don’t remove focus styles; addaria-labelor visible labels where needed. - Variants: Many components (Button, Badge, Alert) use variants (e.g. default, secondary, destructive, outline, ghost). Prefer these over one-off custom classes so the UI stays coherent.
Component Overview (by category)
Use this map to choose the right building block. If a component isn’t in the project, add it via the shadcn CLI (pnpm dlx shadcn@latest add <component>) or copy from the shadcn registry.
Form & input
- Button — Actions; use variants (default, destructive, outline, ghost, link).
- Input, Textarea — Text fields; pair with Label and error message markup.
- Checkbox, Radio Group, Switch, Slider — Selections and toggles.
- Select — Single choice dropdown.
- Combobox — Searchable select / autocomplete.
- Calendar, Date Picker — Date selection.
- Field — Label + input + description + error in one composable.
- Form — With React Hook Form or TanStack Form for validation and submission.
Layout & navigation
- Card — Content containers (header, content, footer).
- Tabs — Tabbed content.
- Accordion, Collapsible — Expand/collapse sections.
- Separator — Visual dividers.
- Scroll Area — Custom scrollable regions.
- Sidebar — App sidebar layout.
- Breadcrumb, Navigation Menu — Navigation.
Overlays & dialogs
- Dialog — Modal.
- Alert Dialog — Confirmations (e.g. delete).
- Sheet — Slide-out panel (drawer).
- Drawer — Mobile-friendly drawer (e.g. Vaul).
- Popover — Floating panel (e.g. for date picker or filters).
- Tooltip, Hover Card — Context on hover.
- Dropdown Menu, Context Menu, Menubar — Menus.
- Command — Command palette (cmdk).
Feedback & status
- Alert — Inline messages (info, warning, error).
- Toast (Sonner) — Notifications.
- Progress, Skeleton, Spinner — Loading and progress.
- Badge — Labels and status chips.
- Empty — Empty state.
Display & media
- Table — Data tables; Data Table for sort/filter/pagination.
- Avatar — User avatars.
- Chart — Recharts-based charts.
- Carousel — Image/content carousel.
- Aspect Ratio — Fixed aspect ratio wrapper.
Implementation Tips
- Import from aliases: Use
~/components/ui/button,~/lib/utils, etc., as incomponents.json. - Extend with
className: PassclassNameinto shadcn components and merge withcn()so layout and one-off styling stay flexible without forking the component. - Use variants first: Before adding custom classes for state (e.g. “danger button”), check if a variant already exists (e.g.
variant="destructive"). - Compose overlays correctly: Dialogs, sheets, and popovers often need a trigger and content; follow the component’s composition (e.g.
DialogTrigger,DialogContent) and keep focus and accessibility in mind. - Forms: Prefer the Field component plus React Hook Form or TanStack Form for validation and errors; wire shadcn Input/Select/Checkbox into the form state.
- Icons: Many projects use lucide-react; use icon names that match the design (e.g. ChevronDown for selects, Loader2 for loading).
Reference
- shadcn/ui docs — Introduction, installation, theming.
- Components — Full list and usage.
- Theming — CSS variables and base colors.
- llms.txt — Concise overview for AI/LLMs.
When in doubt, prefer the documented composition and semantic tokens; that keeps UIs consistent, themeable, and accessible without reinventing patterns.