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.