skills/curated/shadcn/SKILL.md
Best practices for building UI components with shadcn/ui. Use when creating, customizing, or styling components with shadcn, working with Radix UI primitives, implementing design tokens, or following compound component patterns.
npx skillsauth add pedronauck/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.
This skill provides guidelines, patterns, and best practices for working with shadcn/ui components in this project.
references/patterns.md for comprehensive styling, theming, and component patterns.tailwindcss skill.Always use design system tokens for theme switching compatibility:
Required tokens:
bg-background, bg-card, bg-muted, bg-popovertext-foreground, text-muted-foreground, text-card-foregroundborder-border, border-input, border-ringbg-primary text-primary-foreground, bg-secondary text-secondary-foregroundbg-destructive text-destructive-foreground, bg-accent text-accent-foregroundNever use explicit colors like bg-white, text-black, border-gray-200 - they break theme switching.
Use the CLI to add components, then customize as needed:
npx shadcn@latest add button card dialog
Add custom props and variants while preserving accessibility:
export interface ButtonProps
extends React.ButtonHTMLAttributes<HTMLButtonElement>,
VariantProps<typeof buttonVariants> {
loading?: boolean
}
const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
({ className, variant, size, loading, children, ...props }, ref) => {
return (
<button
className={cn(buttonVariants({ variant, size, className }))}
ref={ref}
disabled={loading || props.disabled}
{...props}
>
{loading && <Loader2 className="mr-2 h-4 w-4 animate-spin" />}
{children}
</button>
)
}
)
Always use separate exports, NOT namespaced properties:
// CORRECT
export const CardTech = CardTechRoot;
export const CardTechHeader = CardHeader;
export const CardTechTitle = CardTitle;
export const CardTechContent = CardContent;
// WRONG - Do not use
export const CardTech = Object.assign(CardTechRoot, {
Header: CardHeader,
Content: CardContent,
});
Never remove Radix UI's accessibility attributes:
<Dialog>
<DialogTrigger asChild>
<Button>Open Dialog</Button>
</DialogTrigger>
<DialogContent>
<DialogHeader>
<DialogTitle>Accessible Title</DialogTitle>
<DialogDescription>
This description helps screen readers understand the dialog's purpose
</DialogDescription>
</DialogHeader>
</DialogContent>
</Dialog>
Use CSS variables for all color values in globals.css:
@layer base {
:root {
--success: 142 76% 36%;
--success-foreground: 355 100% 100%;
}
.dark {
--success: 142 76% 46%;
--success-foreground: 142 76% 10%;
}
}
Before finishing a task involving shadcn/ui:
pnpm run typecheck) and tests (pnpm run test).For comprehensive patterns, component examples, and detailed guidelines, read references/patterns.md.
testing
Assess DDD fit; discover domains with EventStorming, define language and bounded contexts, and design aggregates, value objects, events, and repositories. Excludes architecture-only audits, product specs, and CQRS/Event Sourcing catalogs.
development
Build terminal UIs with ratatui following 2026 Rust best practices. Use when: (1) Creating new TUI apps, (2) Adding widgets/layouts, (3) Keyboard navigation/state management, (4) Image integration via ratatui-image, (5) Async event handling, (6) Release optimization. Covers v0.30.0+ API, Elm Architecture, StatefulWidget, color-eyre.
development
Find 10x product opportunities and high-leverage improvements. Use when user wants strategic product thinking, mentions '10x', wants to find high-impact features, or says 'what would make this 10x better', 'product strategy', or 'what should we build next'.
development
You MUST use this before any creative work - creating features, building components, adding functionality, or modifying behavior. Explores user intent, requirements and design before implementation.