skills/shadcn/SKILL.md
--- name: shadcn/ui description: Complete guide con contexto de uso license: MIT metadata: author: next-agent-template version: "1.0" scope: [root, ui, components] auto_invoke: - "Adding shadcn components" - "Working with shadcn/ui" - "Creating shadcn components" - "Styling components with Tailwind" - "Setting up component themes" - "Composing UI layouts" - "Fixing component styling" - "Customizing component variants" - "shadcn init" - "create an app with --preset"
npx skillsauth add jovivaspo/base-agent-next-app skills/shadcnInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
name: shadcn/ui description: Complete guide con contexto de uso license: MIT metadata: author: next-agent-template version: "1.0" scope: [root, ui, components] auto_invoke:
shadcn/ui is a framework for building UI components and design systems. Components are added as source code to your project via CLI.
shadcn/ui es un framework para construir componentes UI y sistemas de diseño. Los componentes se añaden como código fuente a tu proyecto mediante CLI.
variant="outline", size="sm", etc.bg-primary, text-muted-foreground — never raw valuesbg-blue-500| ❌ Wrong | ✅ Correct |
|---------|-----------|
| space-y-4 | flex flex-col gap-4 |
| space-x-4 | flex gap-4 |
| w-10 h-10 | size-10 |
| overflow-hidden text-ellipsis whitespace-nowrap | truncate |
| Manual dark: overrides | Semantic tokens (bg-background) |
// ✅ Correct way
<FieldGroup>
<Field>
<FieldLabel htmlFor="email">Email</FieldLabel>
<Input id="email" />
</Field>
</FieldGroup>
// ❌ Never use raw div with space-y-*
<div className="space-y-4">
<label>Email</label>
<input />
</div>
Validation | Validación:
data-invalid on Fieldaria-invalid on the control<Field data-invalid>
<FieldLabel>Email</FieldLabel>
<Input aria-invalid />
<FieldDescription>Invalid email.</FieldDescription>
</Field>
SelectItem → SelectGroupTitle (accessibility)CardHeader / CardTitle / CardContent / CardFooterAvatar always needs AvatarFallbackTabsTrigger must be inside TabsList// ✅ Correct: data-icon on icon, no sizing classes
<Button>
<SearchIcon data-icon="inline-start" />
Search
</Button>
// ❌ Wrong: sizing classes on icon
<Button>
<SearchIcon className="w-4 h-4" />
Search
</Button>
| Need | Use | Necesidad | Usar |
|------|-----|-----------|------|
| Button/action | Button | Botón/acción | Button |
| Form inputs | Input, Select, Checkbox, Textarea | Inputs de formulario | Input, Select, Checkbox, Textarea |
| Toggle 2–5 options | ToggleGroup | Toggle 2-5 opciones | ToggleGroup |
| Data display | Table, Card, Badge, Avatar | Mostrar datos | Table, Card, Badge, Avatar |
| Navigation | Sidebar, Tabs, Pagination, Breadcrumb | Navegación | Sidebar, Tabs, Pagination, Breadcrumb |
| Overlays | Dialog (modal), Sheet, Drawer, AlertDialog | Overlays | Dialog (modal), Sheet, Drawer, AlertDialog |
| Feedback | sonner (toast), Alert, Progress, Skeleton | Feedback | sonner (toast), Alert, Progress, Skeleton |
| Charts | Chart (wraps Recharts) | Gráficos | Chart (wraps Recharts) |
| Empty states | Empty | Estados vacíos | Empty |
| Menus | DropdownMenu, ContextMenu, Menubar | Menús | DropdownMenu, ContextMenu, Menubar |
npx shadcn@latest info --json
Gets: aliases, isRSC, tailwindVersion, base, iconLibrary, packageManager, etc.
Before running add, check if the component already exists.
npx shadcn@latest search @shadcn -q "sidebar"
npx shadcn@latest docs button dialog select
npx shadcn@latest add button card dialog
npx shadcn@latest add button --dry-run
npx shadcn@latest add button --diff button.tsx
After adding components from community registries, check for hardcoded paths and replace with correct aliases.
:root (light) and .dark (dark mode)bg-primary, text-muted-foreground| Variable | Purpose | Propósito |
|----------|---------|-----------|
| --background / --foreground | Page background and text | Fondo de página y texto |
| --primary / --primary-foreground | Primary buttons and actions | Botones primarios |
| --secondary / --secondary-foreground | Secondary actions | Acciones secundarias |
| --muted / --muted-foreground | Muted/disabled states | Estados mutados/deshabilitados |
| --accent / --accent-foreground | Hover and accent | Estados de hover |
| --destructive / --destructive-foreground | Error and destructive | Errores y acciones destructivas |
| --border | Default border color | Color de borde por defecto |
Colors use OKLCH format: --primary: oklch(0.205 0 0)
# Apply a preset code
npx shadcn@latest init --preset a2r6bw --force
# Switch to named preset
npx shadcn@latest init --preset radix-nova --force
Edit the global CSS file (typically globals.css):
:root {
--warning: oklch(0.84 0.16 84);
--warning-foreground: oklch(0.28 0.07 46);
}
.dark {
--warning: oklch(0.41 0.11 46);
--warning-foreground: oklch(0.99 0.02 95);
}
Then register with Tailwind:
/* Tailwind v4 */
@theme inline {
--color-warning: var(--warning);
--color-warning-foreground: var(--warning-foreground);
}
Use in components:
<div className="bg-warning text-warning-foreground">Warning</div>
# New project with preset
npx shadcn@latest init --name my-app --preset base-nova
# New project with specific template
npx shadcn@latest init --name my-app --preset a2r6bw --template vite
# Initialize existing project
npx shadcn@latest init --preset base-nova
npx shadcn@latest add button card dialog
npx shadcn@latest add @magicui/shimmer-button
npx shadcn@latest add --all
npx shadcn@latest add button --dry-run
npx shadcn@latest docs button dialog select
npx shadcn@latest view @shadcn/button
npx shadcn@latest search @shadcn -q "sidebar"
npx shadcn@latest search @tailark -q "stats"
✅ Always use the project's package runner:
npx shadcn@latest for npmpnpm dlx shadcn@latest for pnpmbunx --bun shadcn@latest for bun✅ Check isRSC field: If true, components with useState, useEffect, or event handlers need "use client" directive
✅ Never manually decode preset codes — pass them directly to npx shadcn@latest init --preset <code>
✅ Use cn() for conditional classes instead of template literal ternaries
✅ Never override component colors — use semantic tokens instead
<Button variant="outline" size="sm"><Card className="max-w-md mx-auto">cvatools
Zustand 5 state management patterns. Trigger: When implementing client-side state with Zustand (stores, selectors, persist middleware, slices).
databases
Zod 4 schema validation patterns. Trigger: When creating or updating Zod v4 schemas for validation/parsing (forms, request payloads, adapters), including v3 -> v4 migration patterns.
development
TypeScript strict patterns and best practices. Trigger: When implementing or refactoring TypeScript in .ts/.tsx (types, interfaces, generics, const maps, type guards, removing any, tightening unknown).
development
Test-Driven Development workflow using Vitest + React Testing Library. Trigger: ALWAYS when implementing features, fixing bugs, or refactoring in Next.js. This is a MANDATORY workflow for all TypeScript/React code.