home / skills / gwenwindflower / .charmschool / shadcn-ui
This skill guides you in adding, customizing, and troubleshooting shadcn/ui components with CVA, theming, and architecture guidance.
npx playbooks add skill gwenwindflower/.charmschool --skill shadcn-uiReview the files below or copy the command above to add this skill to your agents.
---
name: shadcn-ui
description: "Guide for working with shadcn/ui components in any project. Use when: (1) Adding shadcn components, (2) Customizing components with variants or styles, (3) Understanding the shadcn system architecture, (4) Troubleshooting shadcn setup or styling issues."
---
# shadcn/ui Components
## Overview
shadcn/ui is a collection of copy-paste components built on Radix UI primitives and styled with Tailwind CSS. You own the code - components are copied into your project, not installed as dependencies.
## Adding Components
**Basic command:**
```bash
pnpm dlx shadcn@latest add <component>
```
**What gets created:**
- Component file in `src/components/ui/` (or configured path)
- Dependencies automatically installed if needed
- Imports use path alias: `@/components/ui/<component>`
**Before adding:**
- Verify `components.json` exists with correct paths
- Check path alias (`@/*`) is configured in tsconfig/vite
- Ensure CSS variables exist for component tokens
## Customization Patterns
### Variants with CVA
Use `class-variance-authority` for size/color/style variants:
```tsx
import { cva, type VariantProps } from "class-variance-authority"
const buttonVariants = cva(
"inline-flex items-center justify-center rounded-md", // base
{
variants: {
variant: {
default: "bg-primary text-primary-foreground",
destructive: "bg-destructive text-destructive-foreground",
outline: "border border-input bg-background",
},
size: {
default: "h-10 px-4 py-2",
sm: "h-9 rounded-md px-3",
lg: "h-11 rounded-md px-8",
},
},
defaultVariants: {
variant: "default",
size: "default",
},
}
)
```
### Extending Components
Add props or wrap with custom logic:
```tsx
interface CustomButtonProps extends ButtonProps {
loading?: boolean
}
export function CustomButton({ loading, children, ...props }: CustomButtonProps) {
return (
<Button disabled={loading || props.disabled} {...props}>
{loading ? <Spinner /> : children}
</Button>
)
}
```
### Composition
Build complex components from primitives:
```tsx
// CommandDialog = Dialog + Command
<Dialog>
<DialogContent>
<Command>
<CommandInput />
<CommandList>
<CommandGroup>
<CommandItem />
</CommandGroup>
</CommandList>
</Command>
</DialogContent>
</Dialog>
```
### Overriding Styles
- **Via className prop:** For one-off changes
- **Edit component file:** For permanent changes to all instances
## The shadcn System
**Philosophy:** Copy-paste, not a package. You own and modify the code.
**Architecture:**
- Radix UI primitives (accessibility, behavior)
- Tailwind for styling via `cn()` utility
- CSS variables for theming (not Tailwind config colors)
- `components.json` controls paths, style preset, icon library
**Theming:**
- Colors use CSS variables: `hsl(var(--primary))`
- Variables defined in global CSS: `:root` and `.dark`
- Not Tailwind config colors - uses `hsl(var(--name))` pattern
## Common Gotchas
- **Path alias:** Components import `@/lib/utils` - alias must exist
- **Peer dependencies:** Check install output for additional packages
- **"use client":** Needed for RSC frameworks (not relevant in Astro islands)
- **Dark mode:** Requires `.dark` class or `dark:` variant setup
- **CSS variables:** Must be defined before adding components that use them
## External Resources
- shadcn/ui docs: <https://ui.shadcn.com/docs>
- Component catalog: <https://ui.shadcn.com/docs/components>
- Theming guide: <https://ui.shadcn.com/docs/theming>
- CVA docs: <https://cva.style/docs>
- Radix primitives: <https://www.radix-ui.com/primitives>
This skill is a practical guide for working with shadcn/ui components in any project. It explains how components are added, customized, themed, and composed, and highlights the system architecture so you can own and modify the copied component code. Use it to speed up integration and avoid common setup mistakes.
shadcn/ui supplies copy-paste-ready components built on Radix UI primitives and styled with Tailwind CSS; components are copied into your repo rather than installed as a runtime package. The tool creates component files, installs required dependencies, and uses path aliases and CSS variables for theming. You then customize components via className, CVA variants, or by editing the component files directly.
Do I need to install a runtime package for shadcn/ui?
No. Components are copied into your project; the CLI may install peer dependencies but there is no single runtime package to import.
Where should I define theme colors used by components?
Define CSS variables in your global CSS—use :root for light and .dark for dark mode. Components use hsl(var(--name)) rather than Tailwind color tokens.