shadcn/ui skill
Manages shadcn components and projects — adding, searching, fixing, debugging, styling, and composing UI, including chat interfaces.
mkdir -p ~/.claude/skills && curl -sL https://codeload.github.com/shadcn-ui/ui/tar.gz/98a1fe67b439 \ | tar -xz -C ~/.claude/skills --strip-components=2 ui-98a1fe67b439/skills/shadcn
~/.claude/skills/shadcn, pinned to commit 98a1fe6 · ✓ run on 25 Sep 2026: all 15 filesFiles of shadcn/ui
Files 15 files
Used from elsewhere in the repo
Show the full text278 lines
| name | description | user-invocable | allowed-tools |
|---|---|---|---|
| shadcn | Manages shadcn components and projects — adding, searching, fixing, debugging, styling, and composing UI, including chat interfaces. 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". | false | 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, orbunx --bun shadcn@latest— based on the project'spackageManager. Examples below usenpx shadcn@latestbut 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 searchto 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 likebg-blue-500.
Critical Rules
These rules are always enforced. Each links to a file with Incorrect/Correct code pairs.
Styling & Tailwind → styling.md
classNamefor layout, not styling. Never override component colors or typography.- No
space-x-*orspace-y-*. Useflexwithgap-*. For vertical stacks,flex flex-col gap-*. - Use
size-*when width and height are equal.size-10notw-10 h-10. - Use
truncateshorthand. Notoverflow-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-indexon overlay components. Dialog, Sheet, Popover, etc. handle their own stacking.
Forms & Inputs → forms.md
- Forms use
FieldGroup+Field. Never use rawdivwithspace-y-*orgrid gap-*for form layout. InputGroupusesInputGroupInput/InputGroupTextarea. Never rawInput/TextareainsideInputGroup.- Buttons inside inputs use
InputGroup+InputGroupAddon. - Option sets (2–7 choices) use
ToggleGroup. Don't loopButtonwith manual active state. FieldSet+FieldLegendfor grouping related checkboxes/radios. Don't use adivwith a heading.- Field validation uses
data-invalid+aria-invalid.data-invalidonField,aria-invalidon the control. For disabled:data-disabledonField,disabledon the control.
Component Structure → composition.md
- Items always inside their Group.
SelectItem→SelectGroup.DropdownMenuItem→DropdownMenuGroup.CommandItem→CommandGroup. - Use
asChild(radix) orrender(base) for custom triggers. Checkbasefield fromnpx shadcn@latest info. → base-vs-radix.md - Dialog, Sheet, and Drawer always need a Title.
DialogTitle,SheetTitle,DrawerTitlerequired for accessibility. UseclassName="sr-only"if visually hidden. - Use full Card composition.
CardHeader/CardTitle/CardDescription/CardContent/CardFooter. Don't dump everything inCardContent. - Button has no
isPending/isLoading. Compose withSpinner+data-icon+disabled. TabsTriggermust be insideTabsList. Never render triggers directly inTabs.Avataralways needsAvatarFallback. For when the image fails to load.
Use Components, Not Custom Markup → composition.md
- Use existing components before custom markup. Check if a component exists before writing a styled
div. - Callouts use
Alert. Don't build custom styled divs. - Empty states use
Empty. Don't build custom empty state markup. - Toast follows the project base. Use
toastfrom thetoastcomponent for Base UI projects. Usetoast()fromsonnerfor Radix and React Aria projects. - Use
Separatorinstead of<hr>or<div className="border-t">. - Use
Skeletonfor loading placeholders. No customanimate-pulsedivs. - Use
Badgeinstead of custom styled spans.
Icons → icons.md
- Icons in
Buttonusedata-icon.data-icon="inline-start"ordata-icon="inline-end"on the icon. - No sizing classes on icons inside components. Components handle icon sizing via CSS. No
size-4orw-4 h-4. - Pass icons as objects, not string keys.
icon={CheckIcon}, not a string lookup.
Chat & Messaging → chat.md
- Chat UI composes the chat primitives. Conversations use
MessageScroller, rows useMessage, surfaces useBubble. Never hand-rolled bubbledivs or a raw scroll container. MessageScrollerowns scroll behavior. Streaming follow, anchoring, and jump-to-latest (MessageScrollerButton) are built in. Don't write auseStickToBottom/ResizeObserverhook.- Attachments use
Attachment; system notes and dividers useMarker. NotItemcards orSeparator+ a label.
CLI
- Never decode preset codes or build preset URLs manually. Use
npx shadcn@latest preset decode <code>,preset url <code>, orpreset open <code>. For project-aware preset detection, usenpx shadcn@latest preset resolve. - Apply preset codes directly with the CLI. Use
npx shadcn@latest apply <code>for existing projects, ornpx shadcn@latest init --preset <code>when initializing.
Key Patterns
These are the most common patterns that differentiate correct shadcn/ui code. For edge cases, see the linked rule files above.
// Form layout: FieldGroup + Field, not div + Label.
<FieldGroup>
<Field>
<FieldLabel htmlFor="email">Email</FieldLabel>
<Input id="email" />
</Field>
</FieldGroup>
// Validation: data-invalid on Field, aria-invalid on the control.
<Field data-invalid>
<FieldLabel>Email</FieldLabel>
<Input aria-invalid />
<FieldDescription>Invalid email.</FieldDescription>
</Field>
// Icons in buttons: data-icon, no sizing classes.
<Button>
<SearchIcon data-icon="inline-start" />
Search
</Button>
// Spacing: gap-*, not space-y-*.
<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
// Status colors: Badge variants or semantic tokens, not raw colors.
<Badge variant="secondary">+20.1%</Badge> // correct
<span className="text-emerald-600">+20.1%</span> // wrong
Component Selection
| Need | Use |
|---|---|
| Button/action | Button with appropriate variant |
| Form inputs | Input, Select, Combobox, Switch, Checkbox, RadioGroup, Textarea, InputOTP, 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 | toast (Base UI), sonner (Radix/Aria), 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 |
| Chat / conversation UI | MessageScroller, Message, Bubble, Attachment, Marker |
Key Fields
The injected project context contains these key fields:
aliases→ use the actual alias prefix for imports (e.g.@/,~/), never hardcode.isRSC→ whentrue, components usinguseState,useEffect, event handlers, or browser APIs need"use client"at the top of the file. Always reference this field when advising on the directive.tailwindVersion→"v4"uses@theme inlineblocks;"v3"usestailwind.config.js.tailwindCssFile→ the global CSS file where custom CSS variables are defined. Always edit this file, never create a new one.style→ component visual treatment (e.g.nova,vega).base→ primitive library (radixorbase). Affects component APIs and available props.iconLibrary→ determines icon imports. Uselucide-reactforlucide,@tabler/icons-reactfortabler, etc. Never assumelucide-react.resolvedPaths→ exact file-system destinations for components, utils, hooks, etc.framework→ routing and file conventions (e.g. Next.js App Router vs Vite SPA).packageManager→ use this for any non-shadcn dependency installs (e.g.pnpm add date-fnsvsnpm install date-fns).preset→ resolved preset code and values for the current project. Usenpx shadcn@latest preset resolve --jsonwhen you only need preset information.
See cli.md — info command for the full field reference.
Component Docs, Examples, and Usage
Run npx shadcn@latest docs <component> to get the URLs for a component's documentation, examples, and API reference. Fetch these URLs to get the actual content.
npx shadcn@latest docs button dialog select
When creating, fixing, debugging, or using a component, always run npx shadcn@latest docs and fetch the URLs first. This ensures you're working with the correct API and usage patterns rather than guessing.
Workflow
- Get project context — already injected above. Run
npx shadcn@latest infoagain if you need to refresh. - Check installed components first — before running
add, always check thecomponentslist from project context or list theresolvedPaths.uidirectory. Don't import components that haven't been added, and don't re-add ones already installed. - Find components —
npx shadcn@latest search. - Get docs and examples — run
npx shadcn@latest docs <component>to get URLs, then fetch them. Usenpx shadcn@latest viewto browse registry items you haven't installed. To preview changes to installed components, usenpx shadcn@latest add --diff. - Install or update —
npx shadcn@latest add. When updating existing components, use--dry-runand--diffto preview changes first (see Updating Components below). - Fix imports in third-party components — After adding components from community registries (e.g.
@bundui,@magicui), check the added non-UI files for hardcoded import paths like@/components/ui/.... These won't match the project's actual aliases. Usenpx shadcn@latest infoto get the correctuialias (e.g.@workspace/ui/components) and rewrite the imports accordingly. The CLI rewrites imports for its own UI files, but third-party registry components may use default paths that don't match the project. - Review added components — After adding a component or block from any registry, always read the added files and verify they are correct. Check for missing sub-components (e.g.
SelectItemwithoutSelectGroup), missing imports, incorrect composition, or violations of the Critical Rules. Also replace any icon imports with the project'siconLibraryfrom the project context (e.g. if the registry item useslucide-reactbut the project useshugeicons, swap the imports and icon names accordingly). Fix all issues before moving on. - Registry must be explicit — When the user asks to add a block or component, do not guess the registry. If no registry is specified (e.g. user says "add a login block" without specifying
@shadcn,@tailark,owner/repo, etc.), ask which registry to use. Never default to a registry on behalf of the user. - Switching presets — Ask the user first: overwrite, partial, merge, or skip?
- Inspect current preset:
npx shadcn@latest preset resolve. Use--jsonwhen you need structured values. - Inspect incoming preset:
npx shadcn@latest preset decode <code>. Usepreset url <code>orpreset open <code>to share or open the preset builder. - Overwrite:
npx shadcn@latest apply <code>. Overwrites detected components, fonts, and CSS variables. - Partial:
npx shadcn@latest apply <code> --only theme,font. Updates only the selected preset parts without reinstalling UI components. Supported values arethemeandfont; comma-separated combinations are allowed.iconis intentionally not supported, because icon changes may require full component reinstall and transforms. - Merge:
npx shadcn@latest init --preset <code> --force --no-reinstall, then runnpx shadcn@latest infoto list installed components, then for each installed component use--dry-runand--diffto smart merge it individually. - Skip:
npx shadcn@latest init --preset <code> --force --no-reinstall. Only updates config and CSS, leaves components as-is. - Important: Always run preset commands inside the user's project directory.
applyonly works in an existing project with acomponents.jsonfile. The CLI automatically preserves the current base (basevsradix) fromcomponents.json. If you must use a scratch/temp directory (e.g. for--dry-runcomparisons), pass--base <current-base>explicitly — preset codes do not encode the base.
- Inspect current preset:
Updating Components
When the user asks to update a component from upstream while keeping their local changes, use --dry-run and --diff to intelligently merge. NEVER fetch raw files from GitHub manually — always use the CLI.
- Run
npx shadcn@latest add <component> --dry-runto see all files that would be affected. - For each file, run
npx shadcn@latest add <component> --diff <file>to see what changed upstream vs local. - Decide per file based on the diff:
- No local changes → safe to overwrite.
- Has local changes → read the local file, analyze the diff, and apply upstream updates while preserving local modifications.
- User says "just update everything" → use
--overwrite, but confirm first.
- Never use
--overwritewithout the user's explicit approval.
Quick Reference
# Create a new project.
npx shadcn@latest init --name my-app --preset base-nova
npx shadcn@latest init --name my-app --preset a2r6bw --template vite
# Create a monorepo project.
npx shadcn@latest init --name my-app --preset base-nova --monorepo
npx shadcn@latest init --name my-app --preset base-nova --template next --monorepo
# Initialize existing project.
npx shadcn@latest init --preset base-nova
npx shadcn@latest init --defaults # shortcut: --template=next --preset=nova (base style implied)
# Apply a preset to an existing project.
npx shadcn@latest apply a2r6bw
npx shadcn@latest apply a2r6bw --only theme
npx shadcn@latest apply a2r6bw --only font
npx shadcn@latest apply a2r6bw --only theme,font
# Inspect preset codes and project preset state.
npx shadcn@latest preset decode a2r6bw
npx shadcn@latest preset url a2r6bw
npx shadcn@latest preset open a2r6bw
npx shadcn@latest preset resolve
npx shadcn@latest preset resolve --json
# Add components.
npx shadcn@latest add button card dialog
npx shadcn@latest add @magicui/shimmer-button
npx shadcn@latest add owner/repo/item
npx shadcn@latest add --all
# Preview changes before adding/updating.
npx shadcn@latest add button --dry-run
npx shadcn@latest add button --diff button.tsx
npx shadcn@latest add @acme/form --view button.tsx
npx shadcn@latest add owner/repo/item --dry-run
# Search registries.
npx shadcn@latest search @shadcn -q "sidebar"
npx shadcn@latest search @tailark -q "stats"
npx shadcn@latest search owner/repo -q "login"
npx shadcn@latest search # all configured registries
npx shadcn@latest search @shadcn -q "menu" -t ui # filter by item type
# Get component docs and example URLs.
npx shadcn@latest docs button dialog select
# View registry item details (for items not yet installed).
npx shadcn@latest view @shadcn/button
npx shadcn@latest view owner/repo/item
Named presets: nova, vega, maia, lyra, mira, luma
Templates: next, vite, start, react-router, astro (all support --monorepo) and laravel (not supported for monorepo)
Preset codes: Version-prefixed base62 strings (e.g. a2r6bw or b0), from ui.shadcn.com.
Detailed References
- rules/forms.md — FieldGroup, Field, InputGroup, ToggleGroup, FieldSet, validation states
- rules/composition.md — Groups, overlays, Card, Tabs, Avatar, Alert, Empty, Toast, Separator, Skeleton, Badge, Button loading
- rules/chat.md — MessageScroller, Message, Bubble, Attachment, Marker; streaming, anchoring, jump-to-latest
- rules/icons.md — data-icon, icon sizing, passing icons as objects
- rules/styling.md — Semantic colors, variants, className, spacing, size, truncate, dark mode, cn(), z-index
- rules/base-vs-radix.md — asChild vs render, Select, ToggleGroup, Slider, Accordion
- cli.md — Commands, flags, presets, templates
- registry.md — Authoring source registries,
include, item definitions, dependencies, GitHub registry rules - customization.md — Theming, CSS variables, extending components
| 1 | |
| 2 | name shadcn |
| 3 | description Manages shadcn components and projects — adding, searching, fixing, debugging, styling, and composing UI, including chat interfaces. 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". |
| 4 | user-invocable false |
| 5 | allowed-tools Bash(npx shadcn@latest *), Bash(pnpm dlx shadcn@latest *), Bash(bunx --bun shadcn@latest *) |
| 6 | |
| 7 | |
| 8 | # shadcn/ui |
| 9 | |
| 10 | A framework for building ui, components and design systems. Components are added as source code to the user's project via the CLI. |
| 11 | |
| 12 | > **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. |
| 13 | |
| 14 | ## Current Project Context |
| 15 | |
| 16 | |
| 17 | !`npx shadcn@latest info --json` |
| 18 | |
| 19 | |
| 20 | 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. |
| 21 | |
| 22 | ## Principles |
| 23 | |
| 24 | **Use existing components first.** Use `npx shadcn@latest search` to check registries before writing custom UI. Check community registries too. |
| 25 | **Compose, don't reinvent.** Settings page = Tabs + Card + form controls. Dashboard = Sidebar + Card + Chart + Table. |
| 26 | **Use built-in variants before custom styles.** `variant="outline"`, `size="sm"`, etc. |
| 27 | **Use semantic colors.** `bg-primary`, `text-muted-foreground` — never raw values like `bg-blue-500`. |
| 28 | |
| 29 | ## Critical Rules |
| 30 | |
| 31 | These rules are **always enforced**. Each links to a file with Incorrect/Correct code pairs. |
| 32 | |
| 33 | ### Styling & Tailwind → [styling.md](./rules/styling.md) |
| 34 | |
| 35 | **`className` for layout, not styling.** Never override component colors or typography. |
| 36 | **No `space-x-*` or `space-y-*`.** Use `flex` with `gap-*`. For vertical stacks, `flex flex-col gap-*`. |
| 37 | **Use `size-*` when width and height are equal.** `size-10` not `w-10 h-10`. |
| 38 | **Use `truncate` shorthand.** Not `overflow-hidden text-ellipsis whitespace-nowrap`. |
| 39 | **No manual `dark:` color overrides.** Use semantic tokens (`bg-background`, `text-muted-foreground`). |
| 40 | **Use `cn()` for conditional classes.** Don't write manual template literal ternaries. |
| 41 | **No manual `z-index` on overlay components.** Dialog, Sheet, Popover, etc. handle their own stacking. |
| 42 | |
| 43 | ### Forms & Inputs → [forms.md](./rules/forms.md) |
| 44 | |
| 45 | **Forms use `FieldGroup` + `Field`.** Never use raw `div` with `space-y-*` or `grid gap-*` for form layout. |
| 46 | **`InputGroup` uses `InputGroupInput`/`InputGroupTextarea`.** Never raw `Input`/`Textarea` inside `InputGroup`. |
| 47 | **Buttons inside inputs use `InputGroup` + `InputGroupAddon`.** |
| 48 | **Option sets (2–7 choices) use `ToggleGroup`.** Don't loop `Button` with manual active state. |
| 49 | **`FieldSet` + `FieldLegend` for grouping related checkboxes/radios.** Don't use a `div` with a heading. |
| 50 | **Field validation uses `data-invalid` + `aria-invalid`.** `data-invalid` on `Field`, `aria-invalid` on the control. For disabled: `data-disabled` on `Field`, `disabled` on the control. |
| 51 | |
| 52 | ### Component Structure → [composition.md](./rules/composition.md) |
| 53 | |
| 54 | **Items always inside their Group.** `SelectItem` → `SelectGroup`. `DropdownMenuItem` → `DropdownMenuGroup`. `CommandItem` → `CommandGroup`. |
| 55 | **Use `asChild` (radix) or `render` (base) for custom triggers.** Check `base` field from `npx shadcn@latest info`. → [base-vs-radix.md] |
| 56 | **Dialog, Sheet, and Drawer always need a Title.** `DialogTitle`, `SheetTitle`, `DrawerTitle` required for accessibility. Use `className="sr-only"` if visually hidden. |
| 57 | **Use full Card composition.** `CardHeader`/`CardTitle`/`CardDescription`/`CardContent`/`CardFooter`. Don't dump everything in `CardContent`. |
| 58 | **Button has no `isPending`/`isLoading`.** Compose with `Spinner` + `data-icon` + `disabled`. |
| 59 | **`TabsTrigger` must be inside `TabsList`.** Never render triggers directly in `Tabs`. |
| 60 | **`Avatar` always needs `AvatarFallback`.** For when the image fails to load. |
| 61 | |
| 62 | ### Use Components, Not Custom Markup → [composition.md](./rules/composition.md) |
| 63 | |
| 64 | **Use existing components before custom markup.** Check if a component exists before writing a styled `div`. |
| 65 | **Callouts use `Alert`.** Don't build custom styled divs. |
| 66 | **Empty states use `Empty`.** Don't build custom empty state markup. |
| 67 | **Toast follows the project base.** Use `toast` from the `toast` component for |
| 68 | Base UI projects. Use `toast()` from `sonner` for Radix and React Aria |
| 69 | projects. |
| 70 | **Use `Separator`** instead of `<hr>` or `<div className="border-t">`. |
| 71 | **Use `Skeleton`** for loading placeholders. No custom `animate-pulse` divs. |
| 72 | **Use `Badge`** instead of custom styled spans. |
| 73 | |
| 74 | ### Icons → [icons.md](./rules/icons.md) |
| 75 | |
| 76 | **Icons in `Button` use `data-icon`.** `data-icon="inline-start"` or `data-icon="inline-end"` on the icon. |
| 77 | **No sizing classes on icons inside components.** Components handle icon sizing via CSS. No `size-4` or `w-4 h-4`. |
| 78 | **Pass icons as objects, not string keys.** `icon={CheckIcon}`, not a string lookup. |
| 79 | |
| 80 | ### Chat & Messaging → [chat.md](./rules/chat.md) |
| 81 | |
| 82 | **Chat UI composes the chat primitives.** Conversations use `MessageScroller`, rows use `Message`, surfaces use `Bubble`. Never hand-rolled bubble `div`s or a raw scroll container. |
| 83 | **`MessageScroller` owns scroll behavior.** Streaming follow, anchoring, and jump-to-latest (`MessageScrollerButton`) are built in. Don't write a `useStickToBottom`/`ResizeObserver` hook. |
| 84 | **Attachments use `Attachment`; system notes and dividers use `Marker`.** Not `Item` cards or `Separator` + a label. |
| 85 | |
| 86 | ### CLI |
| 87 | |
| 88 | **Never decode preset codes or build preset URLs manually.** Use `npx shadcn@latest preset decode <code>`, `preset url <code>`, or `preset open <code>`. For project-aware preset detection, use `npx shadcn@latest preset resolve`. |
| 89 | **Apply preset codes directly with the CLI.** Use `npx shadcn@latest apply <code>` for existing projects, or `npx shadcn@latest init --preset <code>` when initializing. |
| 90 | |
| 91 | ## Key Patterns |
| 92 | |
| 93 | These are the most common patterns that differentiate correct shadcn/ui code. For edge cases, see the linked rule files above. |
| 94 | |
| 95 | |
| 96 | // Form layout: FieldGroup + Field, not div + Label. |
| 97 | <FieldGroup> |
| 98 | <Field> |
| 99 | <FieldLabel htmlFor="email">Email</FieldLabel> |
| 100 | <Input id="email" /> |
| 101 | </Field> |
| 102 | </FieldGroup> |
| 103 | |
| 104 | // Validation: data-invalid on Field, aria-invalid on the control. |
| 105 | <Field data-invalid> |
| 106 | <FieldLabel>Email</FieldLabel> |
| 107 | <Input aria-invalid /> |
| 108 | <FieldDescription>Invalid email.</FieldDescription> |
| 109 | </Field> |
| 110 | |
| 111 | // Icons in buttons: data-icon, no sizing classes. |
| 112 | <Button> |
| 113 | <SearchIcon data-icon="inline-start" /> |
| 114 | Search |
| 115 | </Button> |
| 116 | |
| 117 | // Spacing: gap-*, not space-y-*. |
| 118 | <div className="flex flex-col gap-4"> // correct |
| 119 | <div className="space-y-4"> // wrong |
| 120 | |
| 121 | // Equal dimensions: size-*, not w-* h-*. |
| 122 | <Avatar className="size-10"> // correct |
| 123 | <Avatar className="w-10 h-10"> // wrong |
| 124 | |
| 125 | // Status colors: Badge variants or semantic tokens, not raw colors. |
| 126 | <Badge variant="secondary">+20.1%</Badge> // correct |
| 127 | <span className="text-emerald-600">+20.1%</span> // wrong |
| 128 | |
| 129 | |
| 130 | ## Component Selection |
| 131 | |
| 132 | | Need | Use | |
| 133 | | -------------------------- | --------------------------------------------------------------------------------------------------- | |
| 134 | | Button/action | `Button` with appropriate variant | |
| 135 | | Form inputs | `Input`, `Select`, `Combobox`, `Switch`, `Checkbox`, `RadioGroup`, `Textarea`, `InputOTP`, `Slider` | |
| 136 | | Toggle between 2–5 options | `ToggleGroup` + `ToggleGroupItem` | |
| 137 | | Data display | `Table`, `Card`, `Badge`, `Avatar` | |
| 138 | | Navigation | `Sidebar`, `NavigationMenu`, `Breadcrumb`, `Tabs`, `Pagination` | |
| 139 | | Overlays | `Dialog` (modal), `Sheet` (side panel), `Drawer` (bottom sheet), `AlertDialog` (confirmation) | |
| 140 | | Feedback | `toast` (Base UI), `sonner` (Radix/Aria), `Alert`, `Progress`, `Skeleton`, `Spinner` | |
| 141 | | Command palette | `Command` inside `Dialog` | |
| 142 | | Charts | `Chart` (wraps Recharts) | |
| 143 | | Layout | `Card`, `Separator`, `Resizable`, `ScrollArea`, `Accordion`, `Collapsible` | |
| 144 | | Empty states | `Empty` | |
| 145 | | Menus | `DropdownMenu`, `ContextMenu`, `Menubar` | |
| 146 | | Tooltips/info | `Tooltip`, `HoverCard`, `Popover` | |
| 147 | | Chat / conversation UI | `MessageScroller`, `Message`, `Bubble`, `Attachment`, `Marker` | |
| 148 | |
| 149 | ## Key Fields |
| 150 | |
| 151 | The injected project context contains these key fields: |
| 152 | |
| 153 | **`aliases`** → use the actual alias prefix for imports (e.g. `@/`, `~/`), never hardcode. |
| 154 | **`isRSC`** → when `true`, components using `useState`, `useEffect`, event handlers, or browser APIs need `"use client"` at the top of the file. Always reference this field when advising on the directive. |
| 155 | **`tailwindVersion`** → `"v4"` uses `@theme inline` blocks; `"v3"` uses `tailwind.config.js`. |
| 156 | **`tailwindCssFile`** → the global CSS file where custom CSS variables are defined. Always edit this file, never create a new one. |
| 157 | **`style`** → component visual treatment (e.g. `nova`, `vega`). |
| 158 | **`base`** → primitive library (`radix` or `base`). Affects component APIs and available props. |
| 159 | **`iconLibrary`** → determines icon imports. Use `lucide-react` for `lucide`, `@tabler/icons-react` for `tabler`, etc. Never assume `lucide-react`. |
| 160 | **`resolvedPaths`** → exact file-system destinations for components, utils, hooks, etc. |
| 161 | **`framework`** → routing and file conventions (e.g. Next.js App Router vs Vite SPA). |
| 162 | **`packageManager`** → use this for any non-shadcn dependency installs (e.g. `pnpm add date-fns` vs `npm install date-fns`). |
| 163 | **`preset`** → resolved preset code and values for the current project. Use `npx shadcn@latest preset resolve --json` when you only need preset information. |
| 164 | |
| 165 | See [cli.md — `info` command] for the full field reference. |
| 166 | |
| 167 | ## Component Docs, Examples, and Usage |
| 168 | |
| 169 | Run `npx shadcn@latest docs <component>` to get the URLs for a component's documentation, examples, and API reference. Fetch these URLs to get the actual content. |
| 170 | |
| 171 | |
| 172 | npx shadcn@latest docs button dialog select |
| 173 | |
| 174 | |
| 175 | **When creating, fixing, debugging, or using a component, always run `npx shadcn@latest docs` and fetch the URLs first.** This ensures you're working with the correct API and usage patterns rather than guessing. |
| 176 | |
| 177 | ## Workflow |
| 178 | |
| 179 | **Get project context** — already injected above. Run `npx shadcn@latest info` again if you need to refresh. |
| 180 | **Check installed components first** — before running `add`, always check the `components` list from project context or list the `resolvedPaths.ui` directory. Don't import components that haven't been added, and don't re-add ones already installed. |
| 181 | **Find components** — `npx shadcn@latest search`. |
| 182 | **Get docs and examples** — run `npx shadcn@latest docs <component>` to get URLs, then fetch them. Use `npx shadcn@latest view` to browse registry items you haven't installed. To preview changes to installed components, use `npx shadcn@latest add --diff`. |
| 183 | **Install or update** — `npx shadcn@latest add`. When updating existing components, use `--dry-run` and `--diff` to preview changes first (see [Updating Components] below). |
| 184 | **Fix imports in third-party components** — After adding components from community registries (e.g. `@bundui`, `@magicui`), check the added non-UI files for hardcoded import paths like `@/components/ui/...`. These won't match the project's actual aliases. Use `npx shadcn@latest info` to get the correct `ui` alias (e.g. `@workspace/ui/components`) and rewrite the imports accordingly. The CLI rewrites imports for its own UI files, but third-party registry components may use default paths that don't match the project. |
| 185 | **Review added components** — After adding a component or block from any registry, **always read the added files and verify they are correct**. Check for missing sub-components (e.g. `SelectItem` without `SelectGroup`), missing imports, incorrect composition, or violations of the [Critical Rules]. Also replace any icon imports with the project's `iconLibrary` from the project context (e.g. if the registry item uses `lucide-react` but the project uses `hugeicons`, swap the imports and icon names accordingly). Fix all issues before moving on. |
| 186 | **Registry must be explicit** — When the user asks to add a block or component, **do not guess the registry**. If no registry is specified (e.g. user says "add a login block" without specifying `@shadcn`, `@tailark`, `owner/repo`, etc.), ask which registry to use. Never default to a registry on behalf of the user. |
| 187 | **Switching presets** — Ask the user first: **overwrite**, **partial**, **merge**, or **skip**? |
| 188 | **Inspect current preset**: `npx shadcn@latest preset resolve`. Use `--json` when you need structured values. |
| 189 | **Inspect incoming preset**: `npx shadcn@latest preset decode <code>`. Use `preset url <code>` or `preset open <code>` to share or open the preset builder. |
| 190 | **Overwrite**: `npx shadcn@latest apply <code>`. Overwrites detected components, fonts, and CSS variables. |
| 191 | **Partial**: `npx shadcn@latest apply <code> --only theme,font`. Updates only the selected preset parts without reinstalling UI components. Supported values are `theme` and `font`; comma-separated combinations are allowed. `icon` is intentionally not supported, because icon changes may require full component reinstall and transforms. |
| 192 | **Merge**: `npx shadcn@latest init --preset <code> --force --no-reinstall`, then run `npx shadcn@latest info` to list installed components, then for each installed component use `--dry-run` and `--diff` to [smart merge] it individually. |
| 193 | **Skip**: `npx shadcn@latest init --preset <code> --force --no-reinstall`. Only updates config and CSS, leaves components as-is. |
| 194 | **Important**: Always run preset commands inside the user's project directory. `apply` only works in an existing project with a `components.json` file. The CLI automatically preserves the current base (`base` vs `radix`) from `components.json`. If you must use a scratch/temp directory (e.g. for `--dry-run` comparisons), pass `--base <current-base>` explicitly — preset codes do not encode the base. |
| 195 | |
| 196 | ## Updating Components |
| 197 | |
| 198 | When the user asks to update a component from upstream while keeping their local changes, use `--dry-run` and `--diff` to intelligently merge. **NEVER fetch raw files from GitHub manually — always use the CLI.** |
| 199 | |
| 200 | Run `npx shadcn@latest add <component> --dry-run` to see all files that would be affected. |
| 201 | For each file, run `npx shadcn@latest add <component> --diff <file>` to see what changed upstream vs local. |
| 202 | Decide per file based on the diff: |
| 203 | No local changes → safe to overwrite. |
| 204 | Has local changes → read the local file, analyze the diff, and apply upstream updates while preserving local modifications. |
| 205 | User says "just update everything" → use `--overwrite`, but confirm first. |
| 206 | **Never use `--overwrite` without the user's explicit approval.** |
| 207 | |
| 208 | ## Quick Reference |
| 209 | |
| 210 | |
| 211 | # Create a new project. |
| 212 | npx shadcn@latest init --name my-app --preset base-nova |
| 213 | npx shadcn@latest init --name my-app --preset a2r6bw --template vite |
| 214 | |
| 215 | # Create a monorepo project. |
| 216 | npx shadcn@latest init --name my-app --preset base-nova --monorepo |
| 217 | npx shadcn@latest init --name my-app --preset base-nova --template next --monorepo |
| 218 | |
| 219 | # Initialize existing project. |
| 220 | npx shadcn@latest init --preset base-nova |
| 221 | npx shadcn@latest init --defaults # shortcut: --template=next --preset=nova (base style implied) |
| 222 | |
| 223 | # Apply a preset to an existing project. |
| 224 | npx shadcn@latest apply a2r6bw |
| 225 | npx shadcn@latest apply a2r6bw --only theme |
| 226 | npx shadcn@latest apply a2r6bw --only font |
| 227 | npx shadcn@latest apply a2r6bw --only theme,font |
| 228 | |
| 229 | # Inspect preset codes and project preset state. |
| 230 | npx shadcn@latest preset decode a2r6bw |
| 231 | npx shadcn@latest preset url a2r6bw |
| 232 | npx shadcn@latest preset open a2r6bw |
| 233 | npx shadcn@latest preset resolve |
| 234 | npx shadcn@latest preset resolve --json |
| 235 | |
| 236 | # Add components. |
| 237 | npx shadcn@latest add button card dialog |
| 238 | npx shadcn@latest add @magicui/shimmer-button |
| 239 | npx shadcn@latest add owner/repo/item |
| 240 | npx shadcn@latest add --all |
| 241 | |
| 242 | # Preview changes before adding/updating. |
| 243 | npx shadcn@latest add button --dry-run |
| 244 | npx shadcn@latest add button --diff button.tsx |
| 245 | npx shadcn@latest add @acme/form --view button.tsx |
| 246 | npx shadcn@latest add owner/repo/item --dry-run |
| 247 | |
| 248 | # Search registries. |
| 249 | npx shadcn@latest search @shadcn -q "sidebar" |
| 250 | npx shadcn@latest search @tailark -q "stats" |
| 251 | npx shadcn@latest search owner/repo -q "login" |
| 252 | npx shadcn@latest search # all configured registries |
| 253 | npx shadcn@latest search @shadcn -q "menu" -t ui # filter by item type |
| 254 | |
| 255 | # Get component docs and example URLs. |
| 256 | npx shadcn@latest docs button dialog select |
| 257 | |
| 258 | # View registry item details (for items not yet installed). |
| 259 | npx shadcn@latest view @shadcn/button |
| 260 | npx shadcn@latest view owner/repo/item |
| 261 | |
| 262 | |
| 263 | **Named presets:** `nova`, `vega`, `maia`, `lyra`, `mira`, `luma` |
| 264 | **Templates:** `next`, `vite`, `start`, `react-router`, `astro` (all support `--monorepo`) and `laravel` (not supported for monorepo) |
| 265 | **Preset codes:** Version-prefixed base62 strings (e.g. `a2r6bw` or `b0`), from [ui.shadcn.com]. |
| 266 | |
| 267 | ## Detailed References |
| 268 | |
| 269 | [rules/forms.md] — FieldGroup, Field, InputGroup, ToggleGroup, FieldSet, validation states |
| 270 | [rules/composition.md] — Groups, overlays, Card, Tabs, Avatar, Alert, Empty, Toast, Separator, Skeleton, Badge, Button loading |
| 271 | [rules/chat.md] — MessageScroller, Message, Bubble, Attachment, Marker; streaming, anchoring, jump-to-latest |
| 272 | [rules/icons.md] — data-icon, icon sizing, passing icons as objects |
| 273 | [rules/styling.md] — Semantic colors, variants, className, spacing, size, truncate, dark mode, cn(), z-index |
| 274 | [rules/base-vs-radix.md] — asChild vs render, Select, ToggleGroup, Slider, Accordion |
| 275 | [cli.md] — Commands, flags, presets, templates |
| 276 | [registry.md] — Authoring source registries, `include`, item definitions, dependencies, GitHub registry rules |
| 277 | [customization.md] — Theming, CSS variables, extending components |
| 278 |
Discussion
Browse more free Claude skills or everything in Development.