shadcn/ui - Complete Guide
Overview
shadcn/ui is a modern approach to UI components that provides copy-and-paste components built on top of Radix UI and Tailwind CSS. Unlike traditional component libraries, you own the code and can customize it to your needs.
Core Philosophy
Not a Component Library
- Copy and paste approach: Components are not installed as dependencies
- Full ownership: You have complete control over the code
- No versioning issues: Since you own the code, there are no breaking changes from updates
- Customizable: Modify components to fit your exact needs
Built on Solid Foundations
- Radix UI: Provides unstyled, accessible UI primitives
- Tailwind CSS: Utility-first CSS framework for styling
- TypeScript: Full type safety out of the box
- Accessibility First: All components follow WAI-ARIA guidelines
Key Features
1. Component Distribution Model
- Direct code access instead of npm packages
- Transparent implementation - see exactly how components work
- Easy to debug and modify
- No black box abstractions
2. CLI Tool
# Initialize shadcn in your project
npx shadcn@latest init
# Add individual components
npx shadcn@latest add button
npx shadcn@latest add card
npx shadcn@latest add form3. Theming System
- CSS variables for colors and styling
- Light and dark mode support built-in
- Multiple theme presets available
- Easy to create custom themes
4. AI-Ready Architecture
- Predictable component structure that AI tools can understand
- Easy for LLMs to read, understand, and generate components
- Consistent patterns across all components
Installation & Setup
Prerequisites
- React 18+
- Tailwind CSS 3.4+
- TypeScript (recommended)
Quick Start
- Initialize your project (if not already done)
npx create-next-app@latest my-app --typescript --tailwind --app
cd my-app- Run the shadcn init command
npx shadcn@latest initThis will:
- Install dependencies (
tailwindcss-animate,class-variance-authority, etc.) - Create a
components.jsonconfiguration file - Set up the
cnutility function - Configure your
tailwind.config.js - Add CSS variables for theming
- Configuration options during init:
- Style: Default or New York
- Base color: Slate, Gray, Zinc, Neutral, or Stone
- CSS variables: Yes (recommended)
- Components location:
@/components - Utils location:
@/lib/utils - React Server Components: Yes/No
- Component alias:
@/components/ui
Configuration File (components.json)
{
"$schema": "https://ui.shadcn.com/schema.json",
"style": "default",
"rsc": true,
"tsx": true,
"tailwind": {
"config": "tailwind.config.ts",
"css": "app/globals.css",
"baseColor": "slate",
"cssVariables": true
},
"aliases": {
"components": "@/components",
"utils": "@/lib/utils",
"ui": "@/components/ui"
}
}Complete Component List
Form & Input Components
- Button - Various styles (default, destructive, outline, ghost, link)
- Input - Text input field
- Label - Form label component
- Textarea - Multi-line text input
- Select - Dropdown selection
- Checkbox - Checkbox with label
- Radio Group - Radio button group
- Switch - Toggle switch
- Slider - Range slider
- Form - React Hook Form integration
- Input OTP - One-time password input
Layout Components
- Card - Container with header, content, and footer
- Accordion - Collapsible content sections
- Tabs - Tabbed interface
- Collapsible - Show/hide content
- Resizable - Resizable panels
- Separator - Visual divider
- Aspect Ratio - Maintain aspect ratio
- Scroll Area - Custom scrollbar area
Navigation Components
- Navigation Menu - Site navigation
- Menubar - Application menu
- Breadcrumb - Breadcrumb navigation
- Pagination - Page navigation
- Sidebar - Side navigation panel
Overlay Components
- Dialog - Modal dialog
- Sheet - Slide-out panel
- Alert Dialog - Confirmation dialog
- Drawer - Mobile-friendly drawer
- Popover - Floating content
- Tooltip - Hover tooltips
- Hover Card - Rich hover content
- Context Menu - Right-click menu
- Dropdown Menu - Dropdown actions
Data Display Components
- Table - Data table
- Data Table - Advanced table with sorting/filtering
- Avatar - User avatar
- Badge - Status badges
- Progress - Progress bars
- Skeleton - Loading placeholders
- Alert - Alert messages
- Toast - Toast notifications (via Sonner)
Date & Time Components
- Calendar - Date picker calendar
- Date Picker - Date selection
Visualization Components
- Chart - Charts via Recharts
- Carousel - Image/content carousel
Advanced Components
- Command - Command palette
- Combobox - Searchable select
- Toggle - Toggle button
- Toggle Group - Grouped toggles
Using Components
Adding a Component
# Add a single component
npx shadcn@latest add button
# Add multiple components
npx shadcn@latest add button card dialogUsing in Your Code
import { Button } from "@/components/ui/button";
import {
Card,
CardContent,
CardDescription,
CardFooter,
CardHeader,
CardTitle,
} from "@/components/ui/card";
export function MyComponent() {
return (
<Card>
<CardHeader>
<CardTitle>Card Title</CardTitle>
<CardDescription>Card description</CardDescription>
</CardHeader>
<CardContent>
<p>Card content goes here</p>
</CardContent>
<CardFooter>
<Button>Action</Button>
</CardFooter>
</Card>
);
}Theming & Customization
CSS Variables
All components use CSS variables for theming:
:root {
--background: 0 0% 100%;
--foreground: 222.2 84% 4.9%;
--primary: 222.2 47.4% 11.2%;
--primary-foreground: 210 40% 98%;
--secondary: 210 40% 96.1%;
--secondary-foreground: 222.2 47.4% 11.2%;
/* ... more variables */
}
.dark {
--background: 222.2 84% 4.9%;
--foreground: 210 40% 98%;
/* ... dark mode variables */
}Customizing Components
Since you own the code, you can:
- Modify styles directly in the component files
- Change Tailwind classes
- Add new variants
- Extend functionality
Creating Custom Themes
- Modify CSS variables in your global CSS
- Use the online theme customizer
- Create theme presets
Best Practices
1. Component Organization
- Keep shadcn components in
components/ui/ - Create wrapper components for business logic
- Don't modify shadcn components directly if you need custom behavior
2. Styling Approach
- Use Tailwind classes for styling
- Leverage CSS variables for consistency
- Use the
cn()utility for conditional classes
3. Accessibility
- All components are accessible by default
- Maintain accessibility when customizing
- Test with keyboard navigation and screen readers
4. Performance
- Components are lightweight and performant
- Tree-shaking works automatically
- Only import what you use
5. Version Control
- Commit shadcn components to your repository
- Track changes like any other code
- No need to worry about library updates breaking your app
Integration with Existing Projects
Next.js App Router
- Full support for React Server Components
- Works seamlessly with app directory structure
Vite
- Configure path aliases in
vite.config.ts - Ensure Tailwind is properly configured
Remix
- Add path aliases to
tsconfig.json - Configure Tailwind for Remix
Monorepo Setup
- Can be added to a shared UI package
- Configure
components.jsonper workspace - Share components across applications
Advanced Features
1. Compound Components
Many components use compound patterns:
<Card>
<CardHeader>
<CardTitle>Title</CardTitle>
<CardDescription>Description</CardDescription>
</CardHeader>
<CardContent>Content</CardContent>
<CardFooter>Footer</CardFooter>
</Card>2. Controlled & Uncontrolled
Components support both patterns:
// Controlled
const [value, setValue] = useState("")
<Input value={value} onChange={(e) => setValue(e.target.value)} />
// Uncontrolled
<Input defaultValue="default" />3. Composition
Build complex UIs by composing components:
<Dialog>
<DialogTrigger asChild>
<Button>Open Dialog</Button>
</DialogTrigger>
<DialogContent>
<DialogHeader>
<DialogTitle>Title</DialogTitle>
</DialogHeader>
<Form>
<Input />
<Button type="submit">Submit</Button>
</Form>
</DialogContent>
</Dialog>Ecosystem & Extensions
Official Tools
- v0 by Vercel: AI-Power UI generation using shadcn components
- Theme Editor: Online tool for creating custom themes
Community Extensions
- shadcn-blocks: Premium blocks and templates
- Date Range Picker: Extended date picker functionality
- Auto Form: Generate forms from Zod schemas
- Rich Text Editor: Tiptap-based editor
- Big Calendar: Full-featured calendar component
UI Inspirations
- Multiple theme variations available
- Community-created component examples
- Integration examples with popular frameworks
Migration Guide
From Other Libraries
From MUI/Ant Design
- Components have similar names but different APIs
- Styling is done with Tailwind instead of CSS-in-JS
- You own the code - customize as needed
From Chakra UI
- Similar component composition patterns
- Replace style props with Tailwind classes
- Theme tokens become CSS variables
Why Choose shadcn/ui?
Advantages
- No vendor lock-in: You own the code
- Customizable: Modify anything to fit your needs
- Modern stack: Built on latest React patterns
- Accessible: WCAG compliant out of the box
- Type-safe: Full TypeScript support
- Lightweight: No runtime overhead
- AI-friendly: Predictable patterns for AI tools
Considerations
- Manual updates: You need to manually update components
- Initial setup: Each component needs to be added individually
- Learning curve: Need to understand Radix UI + Tailwind
Conclusion
shadcn/ui represents a paradigm shift in how we think about component libraries. By giving developers full ownership of their UI code while providing high-quality, accessible components as a starting point, it offers the best of both worlds: rapid development and complete customization.
It's particularly well-suited for:
- Teams that need custom designs
- Projects requiring specific modifications
- Applications where bundle size matters
- Developers who want to understand their components
- Projects using AI-assisted development
With its growing ecosystem, strong community support, and adoption by major companies, shadcn/ui is an excellent choice for your default UI library.