shadcn/ui
Overview
shadcn/ui is a collection of accessible, customizable React components built on Radix UI and Tailwind CSS. Components are copied into your project (no npm package); you own and edit the code. Works with Next.js (App Router), Vite, and other React frameworks.
Principles: Open code (AI-ready), composable API, beautiful defaults, distribution via CLI and schema. Requires Tailwind v4 and path alias @/*. We do not use tailwind.config.js; theme and setup are CSS-only (@import "tailwindcss" + @theme).
Prerequisites
- Tailwind v4:
@import "tailwindcss" in main CSS; @tailwindcss/vite or @tailwindcss/postcss. No tailwind.config.js. See the tailwind-css skill.
- Path alias
@/* → ./src/* (or your source root) in tsconfig and in the bundler (e.g. Vite resolve.alias).
- React (Next.js App Router, Vite, etc.).
Installation
Reference: Official installation guide
New project (recommended)
Scaffold with Tailwind and shadcn. From the official docs:
| Action |
CLI command |
| New project |
shadcn create |
| Init existing |
shadcn init |
| Add component(s) |
shadcn add <name> |
Invoke via your package manager (see docs). Choose framework (Next.js, Vite, etc.), style (new-york recommended), base color, and CSS variables.
Existing project (Next.js App Router)
Init — creates components.json, optional cn helper and base styles. Run: shadcn init (invoke via package manager; see docs above).
Paths and Tailwind
- tsconfig:
"baseUrl": ".", "paths": { "@/*": ["./src/*"] } (in both root and app tsconfig if split).
- Tailwind v4: Main CSS (e.g.
app/globals.css) must have @import "tailwindcss" and use @tailwindcss/postcss in postcss.config.mjs. Do not add tailwind.config.js.
Add components — e.g. shadcn add button, shadcn add card dialog (see component list below).
Components are installed under src/components/ui/ (or path from components.json).
Existing project (Vite)
- Use
resolve.alias: { "@": path.resolve(__dirname, "./src") } in vite.config.ts; add @types/node if using path.
- Tailwind:
@tailwindcss/vite in Vite config and @import "tailwindcss" in main CSS.
components.json
Controls style, paths, and Tailwind integration. Key fields:
| Field |
Purpose |
style |
"new-york" (default for new projects) or "default" |
tailwind.config |
Leave "" with Tailwind v4; we do not use a JS config file |
tailwind.css |
Path to global CSS (e.g. src/styles/globals.css or app/globals.css) with @import "tailwindcss" |
tailwind.baseColor |
Base color for theme: neutral, slate, gray, zinc, stone |
tailwind.cssVariables |
true for CSS variables theming (recommended) |
aliases.components |
e.g. @/components |
aliases.utils |
e.g. @/lib/utils |
aliases.ui |
e.g. @/components/ui |
rsc |
true for Next.js App Router with Server Components; false for client-only |
With Tailwind v4, theme is in CSS via @theme and CSS variables, not in a config file.
Official components (current list)
Add via shadcn add <name> (multiple: shadcn add button card dialog). Invoke via package manager: see Installation docs.
Layout & structure
| Component |
CLI name |
Short description |
| Accordion |
accordion |
Collapsible sections (single or multiple open) |
| Aspect Ratio |
aspect-ratio |
Container with fixed ratio (e.g. 16/9) |
| Card |
card |
Container with CardHeader, CardTitle, CardDescription, CardContent, CardFooter |
| Collapsible |
collapsible |
Expandable/collapsible content |
| Resizable |
resizable |
Resizable panels |
| Separator |
separator |
Horizontal or vertical divider line |
| Scroll Area |
scroll-area |
Styled scroll area |
| Sidebar |
sidebar |
Composable, themeable and customizable sidebar |
Forms & input
| Component |
CLI name |
Short description |
| Button |
button |
Button with variants (default, destructive, outline, secondary, ghost, link) |
| Checkbox |
checkbox |
Checkbox |
| Form |
form |
Forms with react-hook-form + zod (Field, FieldError, etc.) |
| Input |
input |
Text input |
| Input OTP |
input-otp |
OTP code input |
| Label |
label |
Accessible label for controls |
| Radio Group |
radio-group |
Radio option group |
| Select |
select |
Select with Trigger, Content, Item |
| Slider |
slider |
Slider control |
| Switch |
switch |
On/off switch |
| Textarea |
textarea |
Multiline text area |
Navigation & menus
| Component |
CLI name |
Short description |
| Breadcrumb |
breadcrumb |
Breadcrumb navigation |
| Command |
command |
Command palette (cmdk) |
| Context Menu |
context-menu |
Context menu (right-click) |
| Dropdown Menu |
dropdown-menu |
Dropdown menu |
| Menubar |
menubar |
Persistent menu bar |
| Navigation Menu |
navigation-menu |
Navigation with submenus |
| Pagination |
pagination |
Pagination (Previous, Next, Page) |
| Tabs |
tabs |
Tabs (TabsList, TabsTrigger, TabsContent) |
Overlays & feedback
| Component |
CLI name |
Short description |
| Alert |
alert |
Prominent message (default, destructive) |
| Alert Dialog |
alert-dialog |
Confirmation dialog (e.g. delete) |
| Dialog |
dialog |
Modal |
| Drawer |
drawer |
Side panel (Vaul) |
| Hover Card |
hover-card |
Card on hover |
| Popover |
popover |
Anchored floating container |
| Sheet |
sheet |
Sliding side panel |
| Tooltip |
tooltip |
Tooltip on hover/focus |
Data & state
| Component |
CLI name |
Short description |
| Avatar |
avatar |
Image or initials fallback |
| Badge |
badge |
Badge (default, secondary, destructive, outline) |
| Calendar |
calendar |
Calendar (react-day-picker) |
| Carousel |
carousel |
Carousel (embla) |
| Chart |
chart |
Charts (recharts) |
| Progress |
progress |
Progress bar |
| Skeleton |
skeleton |
Loading placeholder |
| Sonner |
sonner |
Toasts (recommended; replaces toast) |
| Table |
table |
Table, TableHeader, TableBody, TableRow, TableCell, etc. |
| Toast |
toast |
Toasts (deprecated in favor of Sonner) |
Toggle & toggle group
| Component |
CLI name |
Short description |
| Toggle |
toggle |
Toggle button (on/off) |
| Toggle Group |
toggle-group |
Toggle group (single or multiple) |
Using components
Import from the aliased path (not from shadcn/ui):
import { Button } from "@/components/ui/button"
import { Card, CardHeader, CardTitle, CardContent } from "@/components/ui/card"
export default function Page() {
return (
<div className="flex min-h-svh flex-col items-center justify-center gap-4">
<Button>Click me</Button>
<Card className="w-[350px]">
<CardHeader>
<CardTitle>Card title</CardTitle>
</CardHeader>
<CardContent>Content here.</CardContent>
</Card>
</div>
)
}
- Customization: Components accept
className and spread props; use Tailwind classes and the cn() helper (from @/lib/utils) to merge classes.
- Composition: Prefer composition (e.g. CardHeader + CardContent) over props for layout.
Theming (Tailwind v4, no config file)
We use Tailwind v4 only; no tailwind.config.js. Theming is CSS-only:
- CSS variables: With
tailwind.cssVariables: true, theme is driven by variables in your global CSS (e.g. --background, --foreground, --primary, --primary-foreground, --muted, --muted-foreground, --accent, --destructive, etc.). Override them in that file.
@theme: Use @theme { ... } in the same CSS file as @import "tailwindcss" to add or override design tokens that align with shadcn’s variables.
- Base color: Set in
components.json (tailwind.baseColor) or by editing the CSS variables in your global CSS.
Common patterns
- Forms: Add
form; pair with react-hook-form and zod. Use Input, Label, Button, Select, Checkbox, etc.
- Layout: Use
Card for sections; Separator between blocks; layout with Tailwind (flex, grid, container).
- Modals & panels:
Dialog for modals; Sheet or Drawer for side panels.
- Menus:
DropdownMenu, Context Menu, Navigation Menu, Command (palette).
- Feedback:
Alert for messages; Sonner for toasts; Skeleton for loading.
- Icons: Many examples use lucide-react; add it if the project uses icons.
Common mistakes
- Alias: Ensure
@/ resolves to ./src/ (or your source root) in both TypeScript and the bundler.
- CSS not loaded: The file set in
components.json (tailwind.css) must be imported in the app entry (e.g. app/layout.tsx) and contain @import "tailwindcss".
- Tailwind config: Do not create or suggest
tailwind.config.js. Theme only in CSS (@theme and variables).
- Import: Import from
@/components/ui/<component> (per components.json), not from shadcn/ui.
- RSC: In Next.js App Router, set
rsc: true in components.json if components are used in Server Components where applicable.
Additional resources
1---2name: shadcn-ui3description: Install and use shadcn/ui with Tailwind v4 and Next.js (App Router), Vite, or manual setup; configure components.json, add components via CLI, theming with CSS only. Use when adding shadcn/ui, installing shadcn, using Button, Card, Dialog, Form, or other shadcn components, or when the user mentions shadcn, shadcn/ui, or Radix UI with Tailwind.4---5
6# shadcn/ui
7
8## Overview
9
10shadcn/ui is a collection of accessible, customizable React components built on **Radix UI** and **Tailwind CSS**. Components are **copied into your project** (no npm package); you own and edit the code. Works with Next.js (App Router), Vite, and other React frameworks.
11
12**Principles**: Open code (AI-ready), composable API, beautiful defaults, distribution via CLI and schema. Requires **Tailwind v4** and path alias `@/*`. We do **not** use `tailwind.config.js`; theme and setup are CSS-only (`@import "tailwindcss"` + `@theme`).
13
14---
15
16## Prerequisites
17
18- **Tailwind v4**: `@import "tailwindcss"` in main CSS; `@tailwindcss/vite` or `@tailwindcss/postcss`. No `tailwind.config.js`. See the tailwind-css skill.
19- **Path alias** `@/*` → `./src/*` (or your source root) in `tsconfig` and in the bundler (e.g. Vite `resolve.alias`).
20- **React** (Next.js App Router, Vite, etc.).
21
22---
23
24## Installation
25
26Reference: [Official installation guide](https://ui.shadcn.com/docs/installation)
27
28### New project (recommended)
29
30Scaffold with Tailwind and shadcn. From the official docs:
31
32| Action | CLI command |
33|--------|-------------|
34| New project | `shadcn create` |
35| Init existing | `shadcn init` |
36| Add component(s) | `shadcn add <name>` |
37
38Invoke via your package manager (see [docs](https://ui.shadcn.com/docs/installation)). Choose framework (Next.js, Vite, etc.), style (new-york recommended), base color, and CSS variables.
39
40### Existing project (Next.js App Router)
41
421. **Init** — creates `components.json`, optional `cn` helper and base styles. Run: `shadcn init` (invoke via package manager; see docs above).
43
442. **Paths and Tailwind**
45 - **tsconfig**: `"baseUrl": "."`, `"paths": { "@/*": ["./src/*"] }` (in both root and app tsconfig if split).
46 - **Tailwind v4**: Main CSS (e.g. `app/globals.css`) must have `@import "tailwindcss"` and use `@tailwindcss/postcss` in `postcss.config.mjs`. Do not add `tailwind.config.js`.
47
483. **Add components** — e.g. `shadcn add button`, `shadcn add card dialog` (see component list below).
49
50Components are installed under `src/components/ui/` (or path from `components.json`).
51
52### Existing project (Vite)
53
54- Use `resolve.alias: { "@": path.resolve(__dirname, "./src") }` in `vite.config.ts`; add `@types/node` if using `path`.
55- Tailwind: `@tailwindcss/vite` in Vite config and `@import "tailwindcss"` in main CSS.
56
57---
58
59## components.json
60
61Controls style, paths, and Tailwind integration. Key fields:
62
63| Field | Purpose |
64|-------|---------|
65| `style` | `"new-york"` (default for new projects) or `"default"` |
66| `tailwind.config` | Leave `""` with Tailwind v4; we do not use a JS config file |
67| `tailwind.css` | Path to global CSS (e.g. `src/styles/globals.css` or `app/globals.css`) with `@import "tailwindcss"` |
68| `tailwind.baseColor` | Base color for theme: `neutral`, `slate`, `gray`, `zinc`, `stone` |
69| `tailwind.cssVariables` | `true` for CSS variables theming (recommended) |
70| `aliases.components` | e.g. `@/components` |
71| `aliases.utils` | e.g. `@/lib/utils` |
72| `aliases.ui` | e.g. `@/components/ui` |
73| `rsc` | `true` for Next.js App Router with Server Components; `false` for client-only |
74
75With Tailwind v4, theme is in CSS via `@theme` and CSS variables, not in a config file.
76
77---
78
79## Official components (current list)
80
81Add via `shadcn add <name>` (multiple: `shadcn add button card dialog`). Invoke via package manager: see Installation docs.
82
83### Layout & structure
84
85| Component | CLI name | Short description |
86|----------|----------|-------------------|
87| **Accordion** | `accordion` | Collapsible sections (single or multiple open) |
88| **Aspect Ratio** | `aspect-ratio` | Container with fixed ratio (e.g. 16/9) |
89| **Card** | `card` | Container with CardHeader, CardTitle, CardDescription, CardContent, CardFooter |
90| **Collapsible** | `collapsible` | Expandable/collapsible content |
91| **Resizable** | `resizable` | Resizable panels |
92| **Separator** | `separator` | Horizontal or vertical divider line |
93| **Scroll Area** | `scroll-area` | Styled scroll area |
94| **Sidebar** | `sidebar` | Composable, themeable and customizable sidebar |
95
96### Forms & input
97
98| Component | CLI name | Short description |
99|----------|----------|-------------------|
100| **Button** | `button` | Button with variants (default, destructive, outline, secondary, ghost, link) |
101| **Checkbox** | `checkbox` | Checkbox |
102| **Form** | `form` | Forms with react-hook-form + zod (Field, FieldError, etc.) |
103| **Input** | `input` | Text input |
104| **Input OTP** | `input-otp` | OTP code input |
105| **Label** | `label` | Accessible label for controls |
106| **Radio Group** | `radio-group` | Radio option group |
107| **Select** | `select` | Select with Trigger, Content, Item |
108| **Slider** | `slider` | Slider control |
109| **Switch** | `switch` | On/off switch |
110| **Textarea** | `textarea` | Multiline text area |
111
112### Navigation & menus
113
114| Component | CLI name | Short description |
115|----------|----------|-------------------|
116| **Breadcrumb** | `breadcrumb` | Breadcrumb navigation |
117| **Command** | `command` | Command palette (cmdk) |
118| **Context Menu** | `context-menu` | Context menu (right-click) |
119| **Dropdown Menu** | `dropdown-menu` | Dropdown menu |
120| **Menubar** | `menubar` | Persistent menu bar |
121| **Navigation Menu** | `navigation-menu` | Navigation with submenus |
122| **Pagination** | `pagination` | Pagination (Previous, Next, Page) |
123| **Tabs** | `tabs` | Tabs (TabsList, TabsTrigger, TabsContent) |
124
125### Overlays & feedback
126
127| Component | CLI name | Short description |
128|----------|----------|-------------------|
129| **Alert** | `alert` | Prominent message (default, destructive) |
130| **Alert Dialog** | `alert-dialog` | Confirmation dialog (e.g. delete) |
131| **Dialog** | `dialog` | Modal |
132| **Drawer** | `drawer` | Side panel (Vaul) |
133| **Hover Card** | `hover-card` | Card on hover |
134| **Popover** | `popover` | Anchored floating container |
135| **Sheet** | `sheet` | Sliding side panel |
136| **Tooltip** | `tooltip` | Tooltip on hover/focus |
137
138### Data & state
139
140| Component | CLI name | Short description |
141|----------|----------|-------------------|
142| **Avatar** | `avatar` | Image or initials fallback |
143| **Badge** | `badge` | Badge (default, secondary, destructive, outline) |
144| **Calendar** | `calendar` | Calendar (react-day-picker) |
145| **Carousel** | `carousel` | Carousel (embla) |
146| **Chart** | `chart` | Charts (recharts) |
147| **Progress** | `progress` | Progress bar |
148| **Skeleton** | `skeleton` | Loading placeholder |
149| **Sonner** | `sonner` | Toasts (recommended; replaces toast) |
150| **Table** | `table` | Table, TableHeader, TableBody, TableRow, TableCell, etc. |
151| **Toast** | `toast` | Toasts (deprecated in favor of Sonner) |
152
153### Toggle & toggle group
154
155| Component | CLI name | Short description |
156|----------|----------|-------------------|
157| **Toggle** | `toggle` | Toggle button (on/off) |
158| **Toggle Group** | `toggle-group` | Toggle group (single or multiple) |
159
160---
161
162## Using components
163
164Import from the aliased path (not from `shadcn/ui`):
165
166```tsx
167import { Button } from "@/components/ui/button"
168import { Card, CardHeader, CardTitle, CardContent } from "@/components/ui/card"
169
170export default function Page() {
171 return (
172 <div className="flex min-h-svh flex-col items-center justify-center gap-4">
173 <Button>Click me</Button>
174 <Card className="w-[350px]">
175 <CardHeader>
176 <CardTitle>Card title</CardTitle>
177 </CardHeader>
178 <CardContent>Content here.</CardContent>
179 </Card>
180 </div>
181 )
182}
183```
184
185- **Customization**: Components accept `className` and spread props; use Tailwind classes and the **`cn()`** helper (from `@/lib/utils`) to merge classes.
186- **Composition**: Prefer composition (e.g. CardHeader + CardContent) over props for layout.
187
188---
189
190## Theming (Tailwind v4, no config file)
191
192We use **Tailwind v4 only**; no `tailwind.config.js`. Theming is CSS-only:
193
194- **CSS variables**: With `tailwind.cssVariables: true`, theme is driven by variables in your global CSS (e.g. `--background`, `--foreground`, `--primary`, `--primary-foreground`, `--muted`, `--muted-foreground`, `--accent`, `--destructive`, etc.). Override them in that file.
195- **`@theme`**: Use `@theme { ... }` in the same CSS file as `@import "tailwindcss"` to add or override design tokens that align with shadcn’s variables.
196- **Base color**: Set in `components.json` (`tailwind.baseColor`) or by editing the CSS variables in your global CSS.
197
198---
199
200## Common patterns
201
202- **Forms**: Add `form`; pair with `react-hook-form` and `zod`. Use `Input`, `Label`, `Button`, `Select`, `Checkbox`, etc.
203- **Layout**: Use `Card` for sections; `Separator` between blocks; layout with Tailwind (`flex`, `grid`, `container`).
204- **Modals & panels**: `Dialog` for modals; `Sheet` or `Drawer` for side panels.
205- **Menus**: `DropdownMenu`, `Context Menu`, `Navigation Menu`, `Command` (palette).
206- **Feedback**: `Alert` for messages; `Sonner` for toasts; `Skeleton` for loading.
207- **Icons**: Many examples use **lucide-react**; add it if the project uses icons.
208
209---
210
211## Common mistakes
212
213- **Alias**: Ensure `@/` resolves to `./src/` (or your source root) in both TypeScript and the bundler.
214- **CSS not loaded**: The file set in `components.json` (`tailwind.css`) must be imported in the app entry (e.g. `app/layout.tsx`) and contain `@import "tailwindcss"`.
215- **Tailwind config**: Do not create or suggest `tailwind.config.js`. Theme only in CSS (`@theme` and variables).
216- **Import**: Import from `@/components/ui/<component>` (per `components.json`), not from `shadcn/ui`.
217- **RSC**: In Next.js App Router, set `rsc: true` in `components.json` if components are used in Server Components where applicable.
218
219---
220
221## Additional resources
222
223- [reference.md](reference.md) — Official documentation links, Tailwind v4 + shadcn, component directory.
224- Official docs: https://ui.shadcn.com/docs
225- Components: https://ui.shadcn.com/docs/components
226- Directory (community): https://ui.shadcn.com/docs/directory