- name
- shadcn-setup
- disable-model-invocation
- true
- description
- Sets up shadcn/ui with Tailwind CSS v4 CSS-first configuration — installs packages, generates globals.css with @theme tokens, creates components.json, and adds the cn() utility. Use when starting a new Next.js or React project that needs a shadcn component library, or migrating from shadcn + Tailwind v3.
- metadata
- {"version":"1.0.0","tags":"shadcn, ui, components, tailwind, react, nextjs"}
# shadcn/ui Setup
Sets up shadcn/ui with proper Tailwind CSS v4 configuration. This skill ensures you get the modern CSS-first setup, not the deprecated v3 approach.
## Contract
Inputs:
- Project root directory (defaults to current working directory).
- Optional: theme name (zinc, slate, stone, etc.), component list, router type (app-router or pages-router).
Outputs:
- `globals.css` with `@import "tailwindcss"` and full `@theme` token block.
- `components.json` with CSS-first shadcn config.
- `src/lib/utils.ts` with `cn()` helper.
- Installed packages: `class-variance-authority`, `clsx`, `tailwind-merge`, `lucide-react`, `tailwindcss`, `@tailwindcss/postcss`.
Creates/Modifies:
- `src/app/globals.css` (created or overwritten).
- `components.json` (created or overwritten).
- `src/lib/utils.ts` (created).
- `package.json` (dependencies updated via `bun add`).
- `postcss.config.mjs` (created if absent).
External Side Effects:
- Runs `bun add` to install packages.
- Runs `bunx shadcn@latest add` for any specified components.
Confirmation Required:
- None. Running this skill applies all changes immediately. Review the component list before invoking in an existing project.
Delegates To:
- `bunx shadcn@latest add` for individual component installation.
## Purpose
**IMPORTANT**: shadcn/ui CLI and AI assistants often generate Tailwind v3 configs by default. This skill ensures:
- Tailwind v4 CSS-first configuration
- Proper `@theme` block with shadcn color tokens
- No deprecated `tailwind.config.js` files
- Correct dependency versions
## When to Use
- Setting up a new Next.js project with shadcn/ui
- Adding shadcn/ui to an existing project
- Migrating from shadcn + Tailwind v3 to v4
- Resetting a broken shadcn configuration
## Quick Start
```bash
# Install core dependencies
bun add class-variance-authority clsx tailwind-merge lucide-react
bun add -D tailwindcss @tailwindcss/postcss
# Initialize shadcn (CSS-first, no tailwind.config)
bunx shadcn@latest init
# Install specific components
bunx shadcn@latest add button card input dialog
# Or install an essential starter set
bunx shadcn@latest add button card input label dialog dropdown-menu toast
```
## What Gets Installed
### Dependencies
```json
{
"dependencies": {
"class-variance-authority": "^0.7.0",
"clsx": "^2.1.0",
"tailwind-merge": "^2.2.0",
"lucide-react": "^0.400.0"
},
"devDependencies": {
"tailwindcss": "^4.0.0",
"@tailwindcss/postcss": "^4.0.0"
}
}
```
### File Structure
```
project/
├── src/
│ ├── app/
│ │ └── globals.css # Tailwind v4 + shadcn theme
│ ├── components/
│ │ └── ui/ # shadcn components
│ │ ├── button.tsx
│ │ ├── card.tsx
│ │ └── ...
│ └── lib/
│ └── utils.ts # cn() utility
├── components.json # shadcn config
└── postcss.config.mjs # PostCSS with @tailwindcss/postcss
```
## Tailwind v4 + shadcn CSS Configuration
The skill generates a CSS-first configuration using `@import "tailwindcss"` and an `@theme` block with all shadcn color tokens and border-radius variables.
See `${CLAUDE_SKILL_DIR}/references/shadcn-theme-tokens.md` for the full token block (load when constructing the globals.css file).
## Available Themes
| Theme | Description |
|-------|-------------|
| `default` | shadcn default (neutral grays) |
| `zinc` | Zinc-based neutral |
| `slate` | Slate-based cool neutral |
| `stone` | Stone-based warm neutral |
| `gray` | Pure gray |
| `neutral` | True neutral |
| `red` | Red primary |
| `rose` | Rose primary |
| `orange` | Orange primary |
| `green` | Green primary |
| `blue` | Blue primary |
| `yellow` | Yellow primary |
| `violet` | Violet primary |
## Common Components
Install commonly used components:
```bash
# Essential set
bunx shadcn@latest add button card input label dialog dropdown-menu toast
# Form-focused
bunx shadcn@latest add form input label select checkbox radio-group switch textarea
# Dashboard
bunx shadcn@latest add card table tabs badge avatar dropdown-menu sheet sidebar
```
## components.json Configuration
```json
{
"$schema": "https://ui.shadcn.com/schema.json",
"style": "default",
"rsc": true,
"tsx": true,
"tailwind": {
"config": "",
"css": "src/app/globals.css",
"baseColor": "zinc",
"cssVariables": true,
"prefix": ""
},
"aliases": {
"components": "@/components",
"utils": "@/lib/utils",
"ui": "@/components/ui",
"lib": "@/lib",
"hooks": "@/hooks"
},
"iconLibrary": "lucide"
}
```
**Note**: The `tailwind.config` is empty because we use CSS-first configuration in v4.
## Utils File
```typescript
// src/lib/utils.ts
import { clsx, type ClassValue } from 'clsx';
import { twMerge } from 'tailwind-merge';
export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs));
}
```
## Usage After Setup
### Adding Components
```bash
# Using bunx (recommended with bun)
bunx shadcn@latest add button
# Multiple components
bunx shadcn@latest add card dialog dropdown-menu
```
### Using Components
```tsx
import { Button } from '@/components/ui/button';
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
export function MyComponent() {
return (
<Card>
<CardHeader>
<CardTitle>Welcome</CardTitle>
</CardHeader>
<CardContent>
<Button>Click me</Button>
</CardContent>
</Card>
);
}
```
## Dark Mode Support
The CSS uses `prefers-color-scheme` by default. For manual toggle:
```tsx
// Add to layout.tsx or a theme provider
'use client';
import { useEffect, useState } from 'react';
export function ThemeProvider({ children }: { children: React.ReactNode }) {
const [theme, setTheme] = useState<'light' | 'dark'>('light');
useEffect(() => {
document.documentElement.classList.toggle('dark', theme === 'dark');
}, [theme]);
return (
<ThemeContext.Provider value={{ theme, setTheme }}>
{children}
</ThemeContext.Provider>
);
}
```
Update CSS to use class-based dark mode:
```css
/* Replace @media (prefers-color-scheme: dark) with: */
.dark {
--color-background: hsl(222.2 84% 4.9%);
/* ... rest of dark theme variables */
}
```
## Troubleshooting
### "tailwind.config.js created by shadcn CLI"
Delete it. The CLI sometimes generates v3 configs. Run:
```bash
rm tailwind.config.js tailwind.config.ts
```
### Components not styled correctly
1. Check that `globals.css` is imported in your layout
2. Verify `@import "tailwindcss"` is at the top
3. Ensure `@theme` block contains all required variables
### Type errors with components
Run:
```bash
bun add -D @types/react @types/react-dom
```
### cn() utility not found
Create `src/lib/utils.ts`:
```typescript
import { clsx, type ClassValue } from 'clsx';
import { twMerge } from 'tailwind-merge';
export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs));
}
```
## Validation
After setup, verify no v3 patterns were introduced:
```bash
# Should return nothing (no v3 tailwind.config files)
find . -name "tailwind.config.*" -not -path "*/node_modules/*"
# Should return nothing (no @apply directives)
grep -r "@apply" src/ --include="*.css" 2>/dev/null
# Verify the @import directive is present
grep "@import \"tailwindcss\"" src/app/globals.css
```
View on GitHub