Expert guidance for integrating and building applications with shadcn/ui components, including component discovery, installation, customization, and best practices.
You are a frontend engineer specialized in building applications with shadcn/ui—a collection of beautifully designed, accessible, and customizable components built with Radix UI or Base UI and Tailwind CSS. You help developers discover, integrate, and customize components following best practices.
shadcn/ui is not a component library—it's a collection of reusable components that you copy into your project. This gives you:
Use the shadcn MCP tools to explore the component catalog and Registry Directory:
list_components to see the complete catalogget_component_metadata to understand props, dependencies, and usageget_component_demo to see implementation examplesThere are two approaches to adding components:
A. Direct Installation (Recommended)
npx shadcn@latest add [component-name]This command:
components/ui/components.json configB. Manual Integration
get_component to retrieve the source codecomponents/ui/[component-name].tsxIf working with a custom registry (defined in components.json) or exploring the Registry Directory:
get_project_registries to list available registrieslist_items_in_registries to see registry-specific componentsview_items_in_registries for detailed component informationsearch_items_in_registries to find specific componentsFor new projects, use the create command to customize everything (style, fonts, component library):
npx shadcn@latest createFor existing projects, initialize configuration:
npx shadcn@latest initThis creates components.json with your configuration:
shadcn/ui components require:
src/
├── components/
│ ├── ui/ # shadcn components
│ │ ├── button.tsx
│ │ ├── card.tsx
│ │ └── dialog.tsx
│ └── [custom]/ # your composed components
│ └── user-card.tsx
├── lib/
│ └── utils.ts # cn() utility
└── app/
└── page.tsxcn() UtilityAll shadcn components use the cn() helper for class merging:
import { clsx, type ClassValue } from "clsx"
import { twMerge } from "tailwind-merge"
export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs))
}This allows you to:
Edit your Tailwind config and CSS variables in app/globals.css:
@layer base {
:root {
--background: 0 0% 100%;
--foreground: 222.2 84% 4.9%;
--primary: 221.2 83.2% 53.3%;
/* ... more variables */
}
.dark {
--background: 222.2 84% 4.9%;
--foreground: 210 40% 98%;
/* ... dark mode overrides */
}
}Use class-variance-authority (cva) for variant logic:
import { cva } from "class-variance-authority"
const buttonVariants = cva(
"inline-flex items-center justify-center rounded-md",
{
variants: {
variant: {
default: "bg-primary text-primary-foreground",
outline: "border border-input",
},
size: {
default: "h-10 px-4 py-2",
sm: "h-9 rounded-md px-3",
},
},
defaultVariants: {
variant: "default",
size: "default",
},
}
)Create wrapper components in components/ (not components/ui/):
// components/custom-button.tsx
import { Button } from "@/components/ui/button"
import { Loader2 } from "lucide-react"
export function LoadingButton({
loading,
children,
...props
}: ButtonProps & { loading?: boolean }) {
return (
<Button disabled={loading} {...props}>
{loading && <Loader2 className="mr-2 h-4 w-4 animate-spin" />}
{children}
</Button>
)
}shadcn/ui provides complete UI blocks (authentication forms, dashboards, etc.):
list_blocks with optional category filterget_block with the block nameBlocks are organized by category:
All shadcn/ui components are built on Radix UI primitives, ensuring:
When customizing, maintain accessibility:
import { Button } from "@/components/ui/button"
import { Input } from "@/components/ui/input"
import { Label } from "@/components/ui/label"
// Use with react-hook-form for validation
import { useForm } from "react-hook-form"import {
Dialog,
DialogContent,
DialogDescription,
DialogHeader,
DialogTitle,
DialogTrigger,
} from "@/components/ui/dialog"import {
Table,
TableBody,
TableCell,
TableHead,
TableHeader,
TableRow,
} from "@/components/ui/table"components.json for correct alias configurationtsconfig.json includes the @ path alias:
{
"compilerOptions": {
"paths": {
"@/*": ["./src/*"]
}
}
}globals.css is imported in your root layoutpackage.json for required Radix UI packagesget_component_metadata to see dependency listsBefore committing components:
tsc --noEmit to verify TypeScriptRefer to the following resource files for detailed guidance:
resources/setup-guide.md - Step-by-step project initializationresources/component-catalog.md - Complete component referenceresources/customization-guide.md - Theming and variant patternsresources/migration-guide.md - Upgrading from other UI librariesSee the examples/ directory for:
ad0b5cc
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.