- Learn
- Stack Essentials
- shadcn/ui
- Installation & Setup
Install and configure shadcn/ui in your Next.js project with the CLI and manual setup options.
Installation & Setup
Get shadcn/ui running in your Next.js project. The CLI handles most configuration automatically.
Prerequisites
Before installing shadcn/ui, ensure you have:
- Next.js 13.4+ with App Router
- Tailwind CSS configured
- TypeScript (recommended)
CLI Installation
Initialize shadcn/ui
npx shadcn@latest init
The CLI will ask several questions:
Which style would you like to use? › New York
Which color would you like to use as base color? › Zinc
Do you want to use CSS variables for colors? › yes
Style Options
Default - Rounded corners, subtle shadows
Border radius: 0.5rem
Softer appearance
New York - Sharper edges, more contrast
Border radius: 0.3rem
Bolder, more defined look
Base Colors
Choose your neutral color palette:
| Color | Description | Best For |
|---|---|---|
| Slate | Blue-gray undertones | Modern, professional |
| Gray | Pure neutral | Minimal, clean |
| Zinc | Warm gray | Balanced, versatile |
| Neutral | True neutral | Maximum flexibility |
| Stone | Warm undertones | Organic, friendly |
CSS Variables
Recommended: Yes
Using CSS variables enables:
- Runtime theme switching
- Dark mode support
- Easy color customization
Generated Files
After initialization, shadcn/ui creates:
project/
├── components/
│ └── ui/ # Component files go here
├── lib/
│ └── utils.ts # cn() utility function
├── app/
│ └── globals.css # Updated with CSS variables
├── components.json # shadcn/ui configuration
└── tailwind.config.ts # Updated configuration
components.json
Configuration file for the CLI:
{
"$schema": "https://ui.shadcn.com/schema.json",
"style": "new-york",
"rsc": true,
"tsx": true,
"tailwind": {
"config": "tailwind.config.ts",
"css": "app/globals.css",
"baseColor": "zinc",
"cssVariables": true,
"prefix": ""
},
"aliases": {
"components": "@/components",
"utils": "@/lib/utils",
"ui": "@/components/ui",
"lib": "@/lib",
"hooks": "@/hooks"
}
}
The utils.ts File
// lib/utils.ts
import { clsx, type ClassValue } from "clsx"
import { twMerge } from "tailwind-merge"
export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs))
}
This utility merges Tailwind classes intelligently.
Updated globals.css
Tailwind v4 (Current):
@import "tailwindcss";
@theme {
/* shadcn/ui CSS variables */
--color-background: hsl(var(--background));
--color-foreground: hsl(var(--foreground));
--color-primary: hsl(var(--primary));
--color-primary-foreground: hsl(var(--primary-foreground));
/* ... other theme colors */
--radius-lg: var(--radius);
}
:root {
--background: 0 0% 100%;
--foreground: 240 10% 3.9%;
--primary: 240 5.9% 10%;
--primary-foreground: 0 0% 98%;
--secondary: 240 4.8% 95.9%;
--secondary-foreground: 240 5.9% 10%;
--muted: 240 4.8% 95.9%;
--muted-foreground: 240 3.8% 46.1%;
--accent: 240 4.8% 95.9%;
--accent-foreground: 240 5.9% 10%;
--destructive: 0 84.2% 60.2%;
--destructive-foreground: 0 0% 98%;
--border: 240 5.9% 90%;
--input: 240 5.9% 90%;
--ring: 240 5.9% 10%;
--radius: 0.5rem;
}
.dark {
--background: 240 10% 3.9%;
--foreground: 0 0% 98%;
/* ... dark mode variables */
}
* {
@apply border-border;
}
body {
@apply bg-background text-foreground;
}
Tailwind v3 (Legacy):
@tailwind base;
@tailwind components;
@tailwind utilities;
@layer base {
:root {
--background: 0 0% 100%;
/* ... same variables */
}
}
Note: shadcn/ui CLI v4+ automatically generates Tailwind v4-compatible CSS.
Adding Components
Using the CLI
Add components as needed:
# Add a single component
npx shadcn@latest add button
# Add multiple components
npx shadcn@latest add button card input
# Add all components (not recommended)
npx shadcn@latest add --all
What Happens When You Add
npx shadcn@latest add button
- CLI downloads component code
- Places it in
components/ui/button.tsx - Installs any required dependencies
- Component is ready to use
Component Dependencies
Some components require others:
# Dialog requires these dependencies
npx shadcn@latest add dialog
# Installs: @radix-ui/react-dialog
# Form requires multiple packages
npx shadcn@latest add form
# Installs: react-hook-form, @hookform/resolvers, zod
Manual Installation
If you prefer manual setup or need custom configuration:
1. Install Dependencies
npm install tailwindcss-animate class-variance-authority clsx tailwind-merge
npm install @radix-ui/react-slot
2. Create utils.ts
// lib/utils.ts
import { clsx, type ClassValue } from "clsx"
import { twMerge } from "tailwind-merge"
export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs))
}
3. Update tailwind.config.ts
import type { Config } from "tailwindcss"
const config: Config = {
darkMode: ["class"],
content: [
"./pages/**/*.{ts,tsx}",
"./components/**/*.{ts,tsx}",
"./app/**/*.{ts,tsx}",
],
theme: {
container: {
center: true,
padding: "2rem",
screens: {
"2xl": "1400px",
},
},
extend: {
colors: {
border: "hsl(var(--border))",
input: "hsl(var(--input))",
ring: "hsl(var(--ring))",
background: "hsl(var(--background))",
foreground: "hsl(var(--foreground))",
primary: {
DEFAULT: "hsl(var(--primary))",
foreground: "hsl(var(--primary-foreground))",
},
secondary: {
DEFAULT: "hsl(var(--secondary))",
foreground: "hsl(var(--secondary-foreground))",
},
destructive: {
DEFAULT: "hsl(var(--destructive))",
foreground: "hsl(var(--destructive-foreground))",
},
muted: {
DEFAULT: "hsl(var(--muted))",
foreground: "hsl(var(--muted-foreground))",
},
accent: {
DEFAULT: "hsl(var(--accent))",
foreground: "hsl(var(--accent-foreground))",
},
popover: {
DEFAULT: "hsl(var(--popover))",
foreground: "hsl(var(--popover-foreground))",
},
card: {
DEFAULT: "hsl(var(--card))",
foreground: "hsl(var(--card-foreground))",
},
},
borderRadius: {
lg: "var(--radius)",
md: "calc(var(--radius) - 2px)",
sm: "calc(var(--radius) - 4px)",
},
keyframes: {
"accordion-down": {
from: { height: "0" },
to: { height: "var(--radix-accordion-content-height)" },
},
"accordion-up": {
from: { height: "var(--radix-accordion-content-height)" },
to: { height: "0" },
},
},
animation: {
"accordion-down": "accordion-down 0.2s ease-out",
"accordion-up": "accordion-up 0.2s ease-out",
},
},
},
plugins: [require("tailwindcss-animate")],
}
export default config
4. Copy Components Manually
Copy component code from the shadcn/ui website or GitHub repository.
Path Aliases
shadcn/ui expects path aliases. Ensure your tsconfig.json includes:
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@/*": ["./*"]
}
}
}
This enables imports like:
import { Button } from "@/components/ui/button"
import { cn } from "@/lib/utils"
AI Tool Setup
v0 Projects
v0 includes shadcn/ui by default. No setup needed.
Lovable/Bolt Projects
Usually pre-configured. Check for components.json:
# If missing, run init
npx shadcn@latest init
Claude Code Projects
Ask Claude Code to set up shadcn/ui:
Set up shadcn/ui in this Next.js project with the New York style
Verifying Installation
After setup, test with a component:
npx shadcn@latest add button
// app/page.tsx
import { Button } from "@/components/ui/button"
export default function Home() {
return (
<div className="p-8">
<Button>Click me</Button>
<Button variant="outline">Outline</Button>
<Button variant="destructive">Delete</Button>
</div>
)
}
If buttons render correctly with proper styling, setup is complete.
Troubleshooting
"Module not found" Errors
Check path aliases in tsconfig.json:
{
"compilerOptions": {
"paths": {
"@/*": ["./*"]
}
}
}
Styles Not Applying
Ensure globals.css is imported in your root layout:
// app/layout.tsx
import "./globals.css"
Dark Mode Not Working
- Check
darkMode: ["class"]in tailwind.config.ts - Ensure dark mode CSS variables are in globals.css
- Use a theme provider like next-themes
Component Import Errors
Verify the component was added:
ls components/ui/
If missing, add it:
npx shadcn@latest add [component-name]
Summary
- CLI Installation:
npx shadcn@latest inithandles configuration - Add Components:
npx shadcn@latest add [component] - Key Files: components.json, utils.ts, globals.css
- Path Aliases: Required for
@/imports - CSS Variables: Enable theming and dark mode
Next Steps
Learn how to use and compose shadcn/ui components in your applications.