Requires detecting the base from components.json before writing any component code, installing components via bunx --bun shadcn@latest add (never hand-written) to @/modules/cores/shadcn/components/ui/, and covers MCP registry tools (mcp__shadcn__*) for discovering components before implementing. This is the plain-React variant of shadcn/ui — for Next.js App Router see nextjs-shadcn instead.
</objective>
shadcn/ui for React
Accessible, copy-in components on Base UI, Radix UI or React Aria primitives, styled with Tailwind CSS v4.
Agent Workflow (MANDATORY)
Before ANY implementation, spawn 3 agents in parallel, one Agent call each with a name:
- fuse-ai-pilot:explore-codebase - Analyze existing components and patterns
- fuse-ai-pilot:research-expert - Verify latest shadcn/ui docs via Context7/Exa
- mcp__shadcn__* - Search registry for component availability
After implementation, run fuse-ai-pilot:sniper for validation.
Overview
When to Use
- Building UI components for React applications (Vite)
- Need accessible, customizable form components (inputs, selects, checkboxes)
- Implementing dialogs, sheets, drawers, or overlay patterns
- Creating data tables with sorting, filtering, and pagination
- Building navigation menus, sidebars, or command palettes
- Need toast notifications or alert feedback components
Why shadcn/ui
| Feature | Benefit |
|---------|---------|
| Copy/paste model | Components copied to your project, full ownership |
| Choice of base | Base UI (default), Radix UI or React Aria — same component names |
| Tailwind CSS v4 styling | CSS-first theme (@theme inline, OKLCH tokens) |
| TanStack Form ready | Field + FieldError accept Standard Schema issues |
| Lucide icons (default) | iconLibrary in components.json, switchable via migrate icons |
Critical Rules
- Detect the base first - Read
components.jsonstyle:base-*= Base UI,radix-*/new-york= Radix,aria-*= React Aria. Never mix bases in one component - New projects default to Base UI -
initpicks Base UI unless-b radix/-b ariais passed - Composition follows the base - Base UI uses
render={<Button />}; Radix usesasChild. Reference examples marked Radix must be translated on Base UI projects - NEVER create components manually - Always install with
bunx --bun shadcn@latest add(the registry serves the variant for the project's base) - TanStack Form only - NOT React Hook Form; wire errors with
data-invalidonField+aria-invalidon the control - SOLID paths - Components at
@/modules/cores/shadcn/components/ui/
Base Differences That Change Code
| Concern | Base UI (default) | Radix UI |
|---------|-------------------|----------|
| Package | @base-ui/react | radix-ui (unified; migrate radix from @radix-ui/react-*) |
| Trigger as custom element | <DialogTrigger render={<Button />}>Open</DialogTrigger> | <DialogTrigger asChild><Button>Open</Button></DialogTrigger> |
| Select | <Select items={items}>, SelectContent alignItemWithTrigger | SelectContent position="item-aligned" \| "popper" |
| Accordion | multiple, defaultValue={["item-1"]} | type="single" collapsible / type="multiple" |
| Toggle group value | array (defaultValue={["bold"]}), multiple | type="single" \| "multiple" |
| Checkbox indeterminate | indeterminate prop | checked="indeterminate" |
| Drawer | Base UI Drawer (swipeDirection) | Vaul (direction) |
| Toasts | add toast → toast.add({ title }) | add sonner → toast("…") from sonner |
| Open-state styling | data-open / data-closed | data-state="open" (both covered by data-open: variant from shadcn/tailwind.css) |
Shared across bases: component names, showCloseButton on DialogContent/SheetContent,
the Field family, theme tokens.
Architecture
Component Foundation
- Primitives - Base UI / Radix UI / React Aria (per
components.json) - Tailwind CSS v4 - CSS-first config:
@import "tailwindcss",@import "shadcn/tailwind.css",@custom-variant dark,@theme inline - class-variance-authority - Variant management for component styles
cnpackage - Registry componentsimport { cn } from "cn"(Sept 2026, drop-in fortwMerge(clsx(...)));lib/utils.tsre-exports it; migrate old projects withshadcn migrate cn
Project Structure
Components installed to @/modules/cores/shadcn/components/ui/ following SOLID architecture. Utils at @/modules/cores/lib/utils.ts (export { cn } from "cn").
MCP Server Integration
Run bunx --bun shadcn@latest mcp init --client claude (or create .mcp.json) for Claude Code integration with the shadcn registry.
Available MCP Tools
mcp__shadcn__search_items_in_registries- Search available componentsmcp__shadcn__view_items_in_registries- View component source codemcp__shadcn__get_item_examples_from_registries- Get usage examplesmcp__shadcn__get_add_command_for_items- Get installation commands
CLI helpers for agents: shadcn info (framework, base, installed components) and shadcn docs <component> -b <base|radix|aria>.
See installation.md for complete setup.
Component Categories
| Category | Components | Primary Reference | |----------|------------|-------------------| | Setup | Init, configuration, theming, icons | installation.md | | Forms | Button, Input, Field, Select, Checkbox, Switch, Slider | field-patterns.md | | Overlay | Dialog, Sheet, Drawer, Popover, Tooltip, HoverCard | dialog.md | | Feedback | Alert, Toast (Base UI) / Sonner (Radix, Aria), Progress, Skeleton, Spinner | toast.md | | Data Display | Table, Badge, Avatar, Calendar, Chart, Carousel | table.md | | Navigation | Breadcrumb, DropdownMenu, Command, Sidebar, Tabs | sidebar.md | | Layout | Card, Accordion, Separator, ScrollArea, Resizable | card.md |
Component references show the Radix API unless marked otherwise; each one lists the Base UI differences at the top.
Best Practices
- Field components -
Field+FieldLabel+FieldError errors={field.state.meta.errors} - Client Components - React apps are client-side by default (
"rsc": false) - Toasts per base - Base UI Toast on Base UI; Sonner on Radix/Aria (the Radix Toast is deprecated)
- MCP tools first - Use
mcp__shadcn__*to explore before implementing - Theming via CSS variables - OKLCH tokens in
src/index.css:root/.dark, exposed with@theme inline - Accessibility - Rely on the primitives' keyboard navigation and ARIA; keep
aria-invalidon invalid controls
Reference Guide
| Need | Reference | |------|-----------| | Initial setup | installation.md, configuration.md | | Form patterns | field-patterns.md, form-examples.md | | Theme customization | theming.md | | Data tables | table.md | | Modal dialogs | dialog.md, alert-dialog.md | | Navigation | sidebar.md, navigation-menu.md |
Scan to join WeChat group