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 form

3. 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

  1. Initialize your project (if not already done)
npx create-next-app@latest my-app --typescript --tailwind --app
cd my-app
  1. Run the shadcn init command
npx shadcn@latest init

This will:

  • Install dependencies (tailwindcss-animate, class-variance-authority, etc.)
  • Create a components.json configuration file
  • Set up the cn utility function
  • Configure your tailwind.config.js
  • Add CSS variables for theming
  1. 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 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 dialog

Using 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:

  1. Modify styles directly in the component files
  2. Change Tailwind classes
  3. Add new variants
  4. Extend functionality

Creating Custom Themes

  1. Modify CSS variables in your global CSS
  2. Use the online theme customizer
  3. 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.json per 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

  1. Components have similar names but different APIs
  2. Styling is done with Tailwind instead of CSS-in-JS
  3. You own the code - customize as needed

From Chakra UI

  1. Similar component composition patterns
  2. Replace style props with Tailwind classes
  3. 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.

On this page