Back to skills
SKILL.md
Library Shadcn
ASecurityProvides shadcn/ui component patterns for React including installation, theming, dark mode, CVA variants, and accessibility with Radix UI primitives. Use when the user asks about building UIs with shadcn/ui, setting up component libraries, customizing themes or dark mode, or composing form patterns. Triggers: shadcn, shadcn/ui, radix, tailwind components, ui library, component library, dark mode.
- 3 stars
- 0 votes
- 0 copies
- 1 view
- Added September 2, 2026
Works with
Security analysis
100/100npx -y skills add Yoodaddy0311/artibot --skill library-shadcn --agent claude-codeAre you the author of Library Shadcn?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/yoodaddy0311-library-shadcn)---
context: fork
name: library-shadcn
description: "Provides shadcn/ui component patterns for React including installation, theming, dark mode, CVA variants, and accessibility with Radix UI primitives. Use when the user asks about building UIs with shadcn/ui, setting up component libraries, customizing themes or dark mode, or composing form patterns. Triggers: shadcn, shadcn/ui, radix, tailwind components, ui library, component library, dark mode."
lang: [en]
level: 2
triggers: ["shadcn", "shadcn/ui", "radix", "tailwind components", "ui library", "component library", "dark mode"]
agents: ["frontend-developer", "architect"]
tokens: "~4K"
category: "library"
platforms: [claude-code, gemini-cli, codex-cli, cursor]
sources:
- "https://ui.shadcn.com/docs"
- "https://www.radix-ui.com/primitives/docs/overview/introduction"
version: "1.0.0"
lastVerified: "2026-06-08"
source_hash: 4dcfbe9a
whenNotToUse: "Non-React frontend stacks (Vue, Svelte, Angular) or projects that do not use Tailwind CSS, where shadcn/ui component patterns cannot be directly applied."
---
# shadcn/ui Component Patterns
## Contents
- [When This Skill Applies](#when-this-skill-applies)
- [Core Guidance](#core-guidance)
- [Anti-Patterns](#anti-patterns)
- [Quick Reference](#quick-reference)
## When This Skill Applies
- Building React UIs with shadcn/ui components
- Setting up theming and dark mode support
- Composing complex UI patterns from primitive components
- Customizing component variants with Tailwind CSS
- Ensuring accessibility compliance in component usage
- Integrating shadcn/ui with Next.js, Remix, or Vite projects
## Core Guidance
### 1. Installation & Setup
**Initialize in a project**:
```bash
npx shadcn@latest init
```
**Add individual components** (not installed as dependency -- copied into your project):
```bash
npx shadcn@latest add button
npx shadcn@latest add dialog
npx shadcn@latest add form
```
**Key Principle**: shadcn/ui copies component source code into your project. You own the code and can customize freely. This is not a traditional npm package.
**Project Structure**:
```
src/
components/
ui/ # shadcn/ui primitives (auto-generated)
button.tsx
dialog.tsx
input.tsx
custom/ # Your compositions using ui primitives
user-form.tsx
data-table.tsx
lib/
utils.ts # cn() utility for class merging
```
### 2. Theming System
**CSS Variables** (defined in `globals.css`):
```css
@layer base {
:root {
--background: 0 0% 100%;
--foreground: 222.2 84% 4.9%;
--primary: 222.2 47.4% 11.2%;
--primary-foreground: 210 40% 98%;
--muted: 210 40% 96.1%;
--muted-foreground: 215.4 16.3% 46.9%;
--border: 214.3 31.8% 91.4%;
--radius: 0.5rem;
}
.dark {
--background: 222.2 84% 4.9%;
--foreground: 210 40% 98%;
--primary: 210 40% 98%;
--primary-foreground: 222.2 47.4% 11.2%;
}
}
```
**Theme Customization Rules**:
- Modify CSS variables, not component source (when possible)
- Use HSL format without the `hsl()` wrapper for variable values
- All shadcn components reference these variables via Tailwind classes
- Generate custom themes at ui.shadcn.com/themes
### 3. Dark Mode Implementation
**Next.js with next-themes**:
```tsx
// app/layout.tsx
import { ThemeProvider } from 'next-themes'
export default function RootLayout({ children }) {
return (
<html lang="en" suppressHydrationWarning>
<body>
<ThemeProvider attribute="class" defaultTheme="system" enableSystem>
{children}
</ThemeProvider>
</body>
</html>
)
}
```
**Theme Toggle Component**:
```tsx
import { Moon, Sun } from 'lucide-react'
import { useTheme } from 'next-themes'
import { Button } from '@/components/ui/button'
export function ThemeToggle() {
const { setTheme, theme } = useTheme()
return (
<Button
variant="ghost"
size="icon"
onClick={() => setTheme(theme === 'light' ? 'dark' : 'light')}
>
<Sun className="h-5 w-5 rotate-0 scale-100 transition-all dark:-rotate-90 dark:scale-0" />
<Moon className="absolute h-5 w-5 rotate-90 scale-0 transition-all dark:rotate-0 dark:scale-100" />
<span className="sr-only">Toggle theme</span>
</Button>
)
}
```
### 4. Component Composition Patterns
**Form with Validation** (React Hook Form + Zod):
```tsx
import { useForm } from 'react-hook-form'
import { zodResolver } from '@hookform/resolvers/zod'
import { z } from 'zod'
import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from '@/components/ui/form'
import { Input } from '@/components/ui/input'
import { Button } from '@/components/ui/button'
const schema = z.object({
email: z.string().email(),
name: z.string().min(2).max(50),
})
export function UserForm() {
const form = useForm({ resolver: zodResolver(schema) })
return (
<Form {...form}>
<form onSubmit={form.handleSubmit(onSubmit)}>
<FormField
control={form.control}
name="email"
render={({ field }) => (
<FormItem>
<FormLabel>Email</FormLabel>
<FormControl>
<Input placeholder="user@example.com" {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<Button type="submit">Submit</Button>
</form>
</Form>
)
}
```
**Data Table Pattern**:
```tsx
import { DataTable } from '@/components/ui/data-table'
import { columns } from './columns'
// columns.tsx defines column config with @tanstack/react-table
// DataTable wraps Table, TableHeader, TableBody, TableRow, TableCell
```
**Dialog with Form**:
```tsx
<Dialog>
<DialogTrigger asChild>
<Button>Open</Button>
</DialogTrigger>
<DialogContent>
<DialogHeader>
<DialogTitle>Edit Profile</DialogTitle>
<DialogDescription>Update your information below.</DialogDescription>
</DialogHeader>
<UserForm />
</DialogContent>
</Dialog>
```
### 5. Component Variants with CVA
**Class Variance Authority** (used internally by shadcn):
```tsx
import { cva, type VariantProps } from 'class-variance-authority'
const badgeVariants = cva(
'inline-flex items-center rounded-full border px-2.5 py-0.5 text-xs font-semibold',
{
variants: {
variant: {
default: 'border-transparent bg-primary text-primary-foreground',
secondary: 'border-transparent bg-secondary text-secondary-foreground',
destructive: 'border-transparent bg-destructive text-destructive-foreground',
outline: 'text-foreground',
},
},
defaultVariants: { variant: 'default' },
}
)
```
**Extending Components**:
```tsx
// Add custom variants by modifying the copied component source
// Or compose with wrapper components for project-specific patterns
```
### 6. Tailwind CSS Integration
**The `cn()` Utility** (essential for class merging):
```tsx
import { clsx, type ClassValue } from 'clsx'
import { twMerge } from 'tailwind-merge'
export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs))
}
// Usage: cn('px-4 py-2', isActive && 'bg-primary', className)
```
**Responsive Design**:
```tsx
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
<Card className="col-span-1 md:col-span-2 lg:col-span-1">
{/* Content */}
</Card>
</div>
```
### 7. Accessibility Guidelines
**Built-in Accessibility** (via Radix UI primitives):
- Keyboard navigation (Tab, Enter, Escape, Arrow keys)
- Focus management and focus trapping in modals
- ARIA attributes automatically applied
- Screen reader announcements for dynamic content
**Your Responsibilities**:
- Always provide `DialogTitle` and `DialogDescription` for dialogs
- Use `sr-only` class for icon-only buttons: `<span className="sr-only">Close</span>`
- Set `aria-label` on interactive elements without visible text
- Maintain color contrast ratios (4.5:1 for normal text, 3:1 for large text)
- Test with keyboard navigation (no mouse)
- Verify with screen reader (VoiceOver, NVDA)
**Focus Management**:
```tsx
// Dialog auto-focuses first focusable element
// Sheet auto-manages focus trap
// Popover returns focus to trigger on close
// Use autoFocus={false} to override default focus behavior
```
### 8. Common Component Patterns
| Pattern | Components Used | Use Case |
|---------|----------------|----------|
| CRUD Table | DataTable + Dialog + Form | Admin panels, data management |
| Command Palette | Command + CommandInput + CommandList | Search, navigation |
| Settings Page | Tabs + Form + Switch + Select | User preferences |
| Dashboard | Card + Chart + Table + Badge | Analytics, overview |
| Auth Pages | Card + Form + Input + Button | Login, signup |
| Navigation | NavigationMenu + Sheet (mobile) | Site header, sidebar |
## Anti-Patterns
- Installing shadcn/ui as an npm package (it copies source files, not a dependency)
- Overriding component styles with `!important` instead of modifying source
- Not using the `cn()` utility for conditional classes
- Forgetting `asChild` prop when wrapping triggers with custom elements
- Missing `DialogTitle` causing accessibility warnings
- Hardcoding colors instead of using CSS variable tokens
## Quick Reference
**Add Component**: `npx shadcn@latest add [component-name]`
**Class Merging**: Always use `cn()` for conditional and merged classes
**Theming**: Modify CSS variables in `globals.css`, not component source
**Dark Mode**: `next-themes` + `attribute="class"` + `.dark` CSS scope
**Forms**: React Hook Form + Zod + shadcn Form components
**Accessibility**: Radix handles ARIA; you handle labels, contrast, and keyboard testing
## Rationalizations
> 이 절은 참고 자료다 — 아래 변명·반박은 모델이 작업 중 스스로 지름길을 점검하는 데 쓰고, 사용자에게 묻는 질문 목록이나 별도 게이트로 쓰지 않는다. 반박에 비추어 스스로 바로잡을 수 없으면 이 스킬의 Step·Checkpoint 규칙을 따른다.
The following table captures common excuses agents make to skip the rigor of this skill, paired with factual rebuttals.
| Excuse | Rebuttal |
|--------|----------|
| "I will build my own components" | shadcn gives you accessible Radix primitives — reinventing means reinventing a11y bugs |
| "copy-paste components are a mess" | shadcn is not a dependency — owning the source is the feature, not the bug |
| "CVA variants are overkill" | variants centralize style decisions; without them you get prop-drilling className everywhere |
| "dark mode with Tailwind is enough" | semantic CSS variables beat dark: prefixes at scale — use shadcn tokens |
| "I will skip Radix and use divs" | divs are not accessible by default — Radix gives you keyboard nav and ARIA for free |
Attribution
Comments
Loading comments…
Newsletter
Get the weekly list of safe new skills, and the ones we pulled.