| name | shadcn |
| description | Manages shadcn components and projects — adding, searching, fixing, debugging, styling, and composing UI. Provides project context, component docs, and usage examples. Applies when working with shadcn/ui, component registries, presets, --preset codes, or any project with a components.json file. Also triggers for "shadcn init", "create an app with --preset", or "switch to --preset". |
| user-invocable | false |
| allowed-tools | Bash(npx shadcn@latest *), Bash(pnpm dlx shadcn@latest *), Bash(bunx --bun shadcn@latest *) |
shadcn/ui
A framework for building ui, components and design systems. Components are added as source code to the user's project via the CLI.
IMPORTANT: Run all CLI commands using the project's package runner: npx shadcn@latest, pnpm dlx shadcn@latest, or bunx --bun shadcn@latest — based on the project's packageManager. Examples below use npx shadcn@latest but substitute the correct runner for the project.
Current Project Context
!`npx shadcn@latest info --json`
The JSON above contains the project config and installed components. Use npx shadcn@latest docs <component> to get documentation and example URLs for any component.
Principles
- Use existing components first. Use
npx shadcn@latest search to check registries before writing custom UI. Check community registries too.
- Compose, don't reinvent. Settings page = Tabs + Card + form controls. Dashboard = Sidebar + Card + Chart + Table.
- Use built-in variants before custom styles.
variant="outline", size="sm", etc.
- Use semantic colors.
bg-primary, text-muted-foreground — never raw values like bg-blue-500.
Critical Rules
These rules are always enforced.
Styling & Tailwind
className for layout, not styling. Never override component colors or typography.
- No
space-x-* or space-y-*. Use flex with gap-*. For vertical stacks, flex flex-col gap-*.
- Use
size-* when width and height are equal. size-10 not w-10 h-10.
- Use
truncate shorthand. Not overflow-hidden text-ellipsis whitespace-nowrap.
- No manual
dark: color overrides. Use semantic tokens (bg-background, text-muted-foreground).
- Use
cn() for conditional classes. Don't write manual template literal ternaries.
- No manual
z-index on overlay components. Dialog, Sheet, Popover, etc. handle their own stacking.
Forms & Inputs
- Forms use
FieldGroup + Field. Never use raw div with space-y-* or grid gap-* for form layout.
InputGroup uses InputGroupInput/InputGroupTextarea. Never raw Input/Textarea inside InputGroup.
- Option sets (2–7 choices) use
ToggleGroup. Don't loop Button with manual active state.
FieldSet + FieldLegend for grouping related checkboxes/radios.
- Field validation uses
data-invalid + aria-invalid.
Component Structure
- Items always inside their Group.
SelectItem → SelectGroup. DropdownMenuItem → DropdownMenuGroup.
- Use
asChild (radix) or render (base) for custom triggers.
- Dialog, Sheet, and Drawer always need a Title.
- Use full Card composition.
CardHeader/CardTitle/CardDescription/CardContent/CardFooter.
- Button has no
isPending/isLoading. Compose with Spinner + data-icon + disabled.
TabsTrigger must be inside TabsList.
Avatar always needs AvatarFallback.
Use Components, Not Custom Markup
- Callouts use
Alert. Don't build custom styled divs.
- Empty states use
Empty. Don't build custom empty state markup.
- Toast via
sonner. Use toast() from sonner.
- Use
Separator instead of <hr> or <div className="border-t">.
- Use
Skeleton for loading placeholders. No custom animate-pulse divs.
- Use
Badge instead of custom styled spans.
Icons
- Icons in
Button use data-icon. data-icon="inline-start" or data-icon="inline-end".
- No sizing classes on icons inside components.
- Pass icons as objects, not string keys.
icon={CheckIcon}, not a string lookup.
Key Patterns
<FieldGroup>
<Field>
<FieldLabel htmlFor="email">Email</FieldLabel>
<Input id="email" />
</Field>
</FieldGroup>
<Field data-invalid>
<FieldLabel>Email</FieldLabel>
<Input aria-invalid />
<FieldDescription>Invalid email.</FieldDescription>
</Field>
<Button>
<SearchIcon data-icon="inline-start" />
Search
</Button>
<div className="flex flex-col gap-4"> // correct
<div className="space-y-4"> // wrong
// Equal dimensions: size-*, not w-* h-*.
<Avatar className="size-10"> // correct
<Avatar className="w-10 h-10"> // wrong
Component Selection
| Need | Use |
|---|
| Button/action | Button with appropriate variant |
| Form inputs | Input, Select, Combobox, Switch, Checkbox, RadioGroup, Textarea, Slider |
| Toggle between 2–5 options | ToggleGroup + ToggleGroupItem |
| Data display | Table, Card, Badge, Avatar |
| Navigation | Sidebar, NavigationMenu, Breadcrumb, Tabs, Pagination |
| Overlays | Dialog (modal), Sheet (side panel), Drawer (bottom sheet), AlertDialog (confirmation) |
| Feedback | sonner (toast), Alert, Progress, Skeleton, Spinner |
| Command palette | Command inside Dialog |
| Charts | Chart (wraps Recharts) |
| Layout | Card, Separator, Resizable, ScrollArea, Accordion, Collapsible |
| Empty states | Empty |
| Menus | DropdownMenu, ContextMenu, Menubar |
| Tooltips/info | Tooltip, HoverCard, Popover |
Workflow
- Get project context — already injected above. Run
pnpm dlx shadcn@latest info again if you need to refresh.
- Check installed components first — before running
add, always check the components list from project context or list the resolvedPaths.ui directory.
- Find components —
pnpm dlx shadcn@latest search.
- Get docs and examples — run
pnpm dlx shadcn@latest docs <component> to get URLs, then fetch them.
- Install or update —
pnpm dlx shadcn@latest add. Use --dry-run and --diff to preview changes first.
- Review added components — After adding, always read the added files and verify they are correct.
Quick Reference
pnpm dlx shadcn@latest add button card dialog
pnpm dlx shadcn@latest search @shadcn -q "sidebar"
pnpm dlx shadcn@latest docs button dialog select
pnpm dlx shadcn@latest add button --dry-run
pnpm dlx shadcn@latest add button --diff button.tsx