shadcn/ui Guide — Copy-Paste React Component Library

Learn shadcn/ui: install components, customize with Tailwind, use with Next.js, and build accessible UIs without a traditional component library dependency.

What Is shadcn/ui?

shadcn/ui is not a traditional component library — it's a collection of reusable components that you copy into your project rather than install as a dependency. Each component is built on Radix UI (for accessibility) and styled with Tailwind CSS.

The key difference: you own the code. Run npx shadcn@latest add button and the button component lands in src/components/ui/button.tsx. You can modify it freely without fighting library internals.

Installation

# Initialize shadcn/ui in a Next.js or Vite project
npx shadcn@latest init

# Follow the prompts to configure:
# - Style (Default or New York)
# - Base color (Slate, Gray, Zinc, Stone, or Neutral)
# - CSS variables for theming

# Add components as needed
npx shadcn@latest add button
npx shadcn@latest add form input label
npx shadcn@latest add dialog dropdown-menu
npx shadcn@latest add table data-table

Using Components

import { Button } from '@/components/ui/button'
import { Input } from '@/components/ui/input'
import { Label } from '@/components/ui/label'
import {
  Dialog, DialogContent, DialogHeader,
  DialogTitle, DialogTrigger,
} from '@/components/ui/dialog'

export function CreatePostDialog() {
  return (
    <Dialog>
      <DialogTrigger asChild>
        <Button>Create Post</Button>
      </DialogTrigger>
      <DialogContent>
        <DialogHeader>
          <DialogTitle>New Post</DialogTitle>
        </DialogHeader>
        <div className="grid gap-4 py-4">
          <div className="grid gap-2">
            <Label htmlFor="title">Title</Label>
            <Input id="title" placeholder="Post title" />
          </div>
        </div>
      </DialogContent>
    </Dialog>
  )
}

Theming and Customization

shadcn/ui uses CSS variables for theming. The globals.css file defines light and dark mode color tokens:

/* globals.css */
:root {{
  --background: 0 0% 100%;
  --foreground: 222.2 84% 4.9%;
  --primary: 221.2 83.2% 53.3%;
  --primary-foreground: 210 40% 98%;
  --radius: 0.5rem;
}}

.dark {{
  --background: 222.2 84% 4.9%;
  --foreground: 210 40% 98%;
  --primary: 217.2 91.2% 59.8%;
}}

Change colors by modifying the CSS variables — every component picks up the change automatically. Use the shadcn/ui theme generator to preview combinations.

Data Table Example

# Install the data table dependencies
npx shadcn@latest add table
npm install @tanstack/react-table
import { useReactTable, getCoreRowModel, flexRender } from '@tanstack/react-table'
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table'

function DataTable<TData>({ columns, data }: {{ columns: ColumnDef<TData>[], data: TData[] }}) {{
  const table = useReactTable({{ data, columns, getCoreRowModel: getCoreRowModel() }})
  
  return (
    <Table>
      <TableHeader>
        {{table.getHeaderGroups().map(headerGroup => (
          <TableRow key={{headerGroup.id}}>
            {{headerGroup.headers.map(header => (
              <TableHead key={{header.id}}>
                {{flexRender(header.column.columnDef.header, header.getContext())}}
              </TableHead>
            ))}}
          </TableRow>
        ))}}
      </TableHeader>
    </Table>
  )
}}

Frequently Asked Questions

Is shadcn/ui compatible with React 19?

Yes. shadcn/ui v2+ supports React 19 with the new JSX transform. Some peer dependency warnings during install are expected and safe to ignore — all components work correctly.

Can I use shadcn/ui without Next.js?

Yes. The CLI supports Vite, Astro, Remix, and any React project with Tailwind CSS. Run npx shadcn@latest init and select your framework.

How do I add dark mode?

shadcn/ui uses the dark class on <html> for dark mode. Use the next-themes library (for Next.js) or implement a theme toggle that adds/removes the class. All CSS variable color tokens automatically switch between light and dark values.