shadcn-setup

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

shadcn/ui Setup

shadcn/ui 配置指南

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.
配置带有正确Tailwind CSS v4设置的shadcn/ui。本指南确保你使用的是现代的CSS优先配置,而非已废弃的v3方案。

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
重要提示:shadcn/ui CLI和AI助手通常默认生成Tailwind v3配置。本指南确保:
  • Tailwind v4 CSS优先配置
  • 包含shadcn颜色令牌的正确
    @theme
  • 无已废弃的
    tailwind.config.js
    文件
  • 正确的依赖版本

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
  • 为新的Next.js项目配置shadcn/ui
  • 为现有项目添加shadcn/ui
  • 从shadcn + Tailwind v3迁移到v4
  • 重置损坏的shadcn配置

Quick Start

快速开始

bash
undefined
bash
undefined

Full setup (recommended)

完整配置(推荐)

python3 ~/.claude/skills/shadcn-setup/scripts/setup.py --root .
python3 ~/.claude/skills/shadcn-setup/scripts/setup.py --root .

With specific theme

指定主题

python3 ~/.claude/skills/shadcn-setup/scripts/setup.py --root . --theme zinc
python3 ~/.claude/skills/shadcn-setup/scripts/setup.py --root . --theme zinc

Install specific components

安装特定组件

python3 ~/.claude/skills/shadcn-setup/scripts/setup.py --root . --components button,card,input,dialog
python3 ~/.claude/skills/shadcn-setup/scripts/setup.py --root . --components button,card,input,dialog

Next.js App Router (default)

Next.js App Router(默认)

python3 ~/.claude/skills/shadcn-setup/scripts/setup.py --root . --app-router
python3 ~/.claude/skills/shadcn-setup/scripts/setup.py --root . --app-router

Next.js Pages Router

Next.js Pages Router

python3 ~/.claude/skills/shadcn-setup/scripts/setup.py --root . --pages-router
undefined
python3 ~/.claude/skills/shadcn-setup/scripts/setup.py --root . --pages-router
undefined

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"
  }
}
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
project/
├── src/
│   ├── app/
│   │   └── globals.css           # Tailwind v4 + shadcn主题
│   ├── components/
│   │   └── ui/                   # shadcn组件
│   │       ├── button.tsx
│   │       ├── card.tsx
│   │       └── ...
│   └── lib/
│       └── utils.ts              # cn()工具函数
├── components.json               # shadcn配置文件
└── postcss.config.mjs            # 集成@tailwindcss/postcss的PostCSS配置

Tailwind v4 + shadcn CSS Configuration

Tailwind v4 + shadcn CSS配置

The skill generates a CSS-first configuration:
css
/* src/app/globals.css */
@import "tailwindcss";

@theme {
  /* Base colors */
  --color-background: hsl(0 0% 100%);
  --color-foreground: hsl(222.2 84% 4.9%);

  /* Card */
  --color-card: hsl(0 0% 100%);
  --color-card-foreground: hsl(222.2 84% 4.9%);

  /* Popover */
  --color-popover: hsl(0 0% 100%);
  --color-popover-foreground: hsl(222.2 84% 4.9%);

  /* Primary */
  --color-primary: hsl(222.2 47.4% 11.2%);
  --color-primary-foreground: hsl(210 40% 98%);

  /* Secondary */
  --color-secondary: hsl(210 40% 96.1%);
  --color-secondary-foreground: hsl(222.2 47.4% 11.2%);

  /* Muted */
  --color-muted: hsl(210 40% 96.1%);
  --color-muted-foreground: hsl(215.4 16.3% 46.9%);

  /* Accent */
  --color-accent: hsl(210 40% 96.1%);
  --color-accent-foreground: hsl(222.2 47.4% 11.2%);

  /* Destructive */
  --color-destructive: hsl(0 84.2% 60.2%);
  --color-destructive-foreground: hsl(210 40% 98%);

  /* Border & Input */
  --color-border: hsl(214.3 31.8% 91.4%);
  --color-input: hsl(214.3 31.8% 91.4%);
  --color-ring: hsl(222.2 84% 4.9%);

  /* Chart colors */
  --color-chart-1: hsl(12 76% 61%);
  --color-chart-2: hsl(173 58% 39%);
  --color-chart-3: hsl(197 37% 24%);
  --color-chart-4: hsl(43 74% 66%);
  --color-chart-5: hsl(27 87% 67%);

  /* Border radius */
  --radius-sm: 0.25rem;
  --radius-md: 0.375rem;
  --radius-lg: 0.5rem;
  --radius-xl: 0.75rem;
  --radius-2xl: 1rem;
  --radius-full: 9999px;

  /* Sidebar (if using sidebar component) */
  --color-sidebar: hsl(0 0% 98%);
  --color-sidebar-foreground: hsl(240 5.3% 26.1%);
  --color-sidebar-primary: hsl(240 5.9% 10%);
  --color-sidebar-primary-foreground: hsl(0 0% 98%);
  --color-sidebar-accent: hsl(240 4.8% 95.9%);
  --color-sidebar-accent-foreground: hsl(240 5.9% 10%);
  --color-sidebar-border: hsl(220 13% 91%);
  --color-sidebar-ring: hsl(217.2 91.2% 59.8%);
}

/* Dark mode */
@media (prefers-color-scheme: dark) {
  @theme {
    --color-background: hsl(222.2 84% 4.9%);
    --color-foreground: hsl(210 40% 98%);
    --color-card: hsl(222.2 84% 4.9%);
    --color-card-foreground: hsl(210 40% 98%);
    --color-popover: hsl(222.2 84% 4.9%);
    --color-popover-foreground: hsl(210 40% 98%);
    --color-primary: hsl(210 40% 98%);
    --color-primary-foreground: hsl(222.2 47.4% 11.2%);
    --color-secondary: hsl(217.2 32.6% 17.5%);
    --color-secondary-foreground: hsl(210 40% 98%);
    --color-muted: hsl(217.2 32.6% 17.5%);
    --color-muted-foreground: hsl(215 20.2% 65.1%);
    --color-accent: hsl(217.2 32.6% 17.5%);
    --color-accent-foreground: hsl(210 40% 98%);
    --color-destructive: hsl(0 62.8% 30.6%);
    --color-destructive-foreground: hsl(210 40% 98%);
    --color-border: hsl(217.2 32.6% 17.5%);
    --color-input: hsl(217.2 32.6% 17.5%);
    --color-ring: hsl(212.7 26.8% 83.9%);
    --color-sidebar: hsl(240 5.9% 10%);
    --color-sidebar-foreground: hsl(240 4.8% 95.9%);
    --color-sidebar-primary: hsl(224.3 76.3% 48%);
    --color-sidebar-primary-foreground: hsl(0 0% 100%);
    --color-sidebar-accent: hsl(240 3.7% 15.9%);
    --color-sidebar-accent-foreground: hsl(240 4.8% 95.9%);
    --color-sidebar-border: hsl(240 3.7% 15.9%);
  }
}

/* Base styles */
* {
  border-color: var(--color-border);
}

body {
  background-color: var(--color-background);
  color: var(--color-foreground);
}
本指南生成的是CSS优先的配置:
css
/* src/app/globals.css */
@import "tailwindcss";

@theme {
  /* 基础颜色 */
  --color-background: hsl(0 0% 100%);
  --color-foreground: hsl(222.2 84% 4.9%);

  /* 卡片 */
  --color-card: hsl(0 0% 100%);
  --color-card-foreground: hsl(222.2 84% 4.9%);

  /* 弹出层 */
  --color-popover: hsl(0 0% 100%);
  --color-popover-foreground: hsl(222.2 84% 4.9%);

  /* 主色调 */
  --color-primary: hsl(222.2 47.4% 11.2%);
  --color-primary-foreground: hsl(210 40% 98%);

  /* 次要色调 */
  --color-secondary: hsl(210 40% 96.1%);
  --color-secondary-foreground: hsl(222.2 47.4% 11.2%);

  /* 弱化色调 */
  --color-muted: hsl(210 40% 96.1%);
  --color-muted-foreground: hsl(215.4 16.3% 46.9%);

  /* 强调色调 */
  --color-accent: hsl(210 40% 96.1%);
  --color-accent-foreground: hsl(222.2 47.4% 11.2%);

  /* 危险色调 */
  --color-destructive: hsl(0 84.2% 60.2%);
  --color-destructive-foreground: hsl(210 40% 98%);

  /* 边框与输入框 */
  --color-border: hsl(214.3 31.8% 91.4%);
  --color-input: hsl(214.3 31.8% 91.4%);
  --color-ring: hsl(222.2 84% 4.9%);

  /* 图表颜色 */
  --color-chart-1: hsl(12 76% 61%);
  --color-chart-2: hsl(173 58% 39%);
  --color-chart-3: hsl(197 37% 24%);
  --color-chart-4: hsl(43 74% 66%);
  --color-chart-5: hsl(27 87% 67%);

  /* 边框圆角 */
  --radius-sm: 0.25rem;
  --radius-md: 0.375rem;
  --radius-lg: 0.5rem;
  --radius-xl: 0.75rem;
  --radius-2xl: 1rem;
  --radius-full: 9999px;

  /* 侧边栏(如果使用侧边栏组件) */
  --color-sidebar: hsl(0 0% 98%);
  --color-sidebar-foreground: hsl(240 5.3% 26.1%);
  --color-sidebar-primary: hsl(240 5.9% 10%);
  --color-sidebar-primary-foreground: hsl(0 0% 98%);
  --color-sidebar-accent: hsl(240 4.8% 95.9%);
  --color-sidebar-accent-foreground: hsl(240 5.9% 10%);
  --color-sidebar-border: hsl(220 13% 91%);
  --color-sidebar-ring: hsl(217.2 91.2% 59.8%);
}

/* 深色模式 */
@media (prefers-color-scheme: dark) {
  @theme {
    --color-background: hsl(222.2 84% 4.9%);
    --color-foreground: hsl(210 40% 98%);
    --color-card: hsl(222.2 84% 4.9%);
    --color-card-foreground: hsl(210 40% 98%);
    --color-popover: hsl(222.2 84% 4.9%);
    --color-popover-foreground: hsl(210 40% 98%);
    --color-primary: hsl(210 40% 98%);
    --color-primary-foreground: hsl(222.2 47.4% 11.2%);
    --color-secondary: hsl(217.2 32.6% 17.5%);
    --color-secondary-foreground: hsl(210 40% 98%);
    --color-muted: hsl(217.2 32.6% 17.5%);
    --color-muted-foreground: hsl(215 20.2% 65.1%);
    --color-accent: hsl(217.2 32.6% 17.5%);
    --color-accent-foreground: hsl(210 40% 98%);
    --color-destructive: hsl(0 62.8% 30.6%);
    --color-destructive-foreground: hsl(210 40% 98%);
    --color-border: hsl(217.2 32.6% 17.5%);
    --color-input: hsl(217.2 32.6% 17.5%);
    --color-ring: hsl(212.7 26.8% 83.9%);
    --color-sidebar: hsl(240 5.9% 10%);
    --color-sidebar-foreground: hsl(240 4.8% 95.9%);
    --color-sidebar-primary: hsl(224.3 76.3% 48%);
    --color-sidebar-primary-foreground: hsl(0 0% 100%);
    --color-sidebar-accent: hsl(240 3.7% 15.9%);
    --color-sidebar-accent-foreground: hsl(240 4.8% 95.9%);
    --color-sidebar-border: hsl(240 3.7% 15.9%);
  }
}

/* 基础样式 */
* {
  border-color: var(--color-border);
}

body {
  background-color: var(--color-background);
  color: var(--color-foreground);
}

Available Themes

可用主题

ThemeDescription
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
主题描述
default
shadcn默认主题(中性灰色系)
zinc
基于Zinc的中性色
slate
基于Slate的冷色调中性色
stone
基于Stone的暖色调中性色
gray
纯灰色系
neutral
纯正中性色
red
红色主色调
rose
玫瑰红主色调
orange
橙色主色调
green
绿色主色调
blue
蓝色主色调
yellow
黄色主色调
violet
紫罗兰色主色调

Common Components

常用组件

Install commonly used components:
bash
undefined
安装常用组件:
bash
undefined

Essential set

基础组件集合

python3 ~/.claude/skills/shadcn-setup/scripts/setup.py --root .
--components button,card,input,label,dialog,dropdown-menu,toast
python3 ~/.claude/skills/shadcn-setup/scripts/setup.py --root .
--components button,card,input,label,dialog,dropdown-menu,toast

Form-focused

表单专属组件

python3 ~/.claude/skills/shadcn-setup/scripts/setup.py --root .
--components form,input,label,select,checkbox,radio-group,switch,textarea
python3 ~/.claude/skills/shadcn-setup/scripts/setup.py --root .
--components form,input,label,select,checkbox,radio-group,switch,textarea

Dashboard

仪表盘组件

python3 ~/.claude/skills/shadcn-setup/scripts/setup.py --root .
--components card,table,tabs,badge,avatar,dropdown-menu,sheet,sidebar
undefined
python3 ~/.claude/skills/shadcn-setup/scripts/setup.py --root .
--components card,table,tabs,badge,avatar,dropdown-menu,sheet,sidebar
undefined

components.json Configuration

components.json 配置

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.
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"
}
注意
tailwind.config
为空,因为我们在v4中使用CSS优先的配置方式。

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));
}
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
undefined
bash
undefined

Using bunx (recommended with bun)

使用bunx(推荐搭配bun使用)

bunx shadcn@latest add button
bunx shadcn@latest add button

Multiple components

多个组件

bunx shadcn@latest add card dialog dropdown-menu
undefined
bunx shadcn@latest add card dialog dropdown-menu
undefined

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>
  );
}
tsx
import { Button } from '@/components/ui/button';
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';

export function MyComponent() {
  return (
    <Card>
      <CardHeader>
        <CardTitle>欢迎</CardTitle>
      </CardHeader>
      <CardContent>
        <Button>点击我</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 */
}
CSS默认使用
prefers-color-scheme
。如需手动切换:
tsx
// 添加到layout.tsx或主题提供者中
'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>
  );
}
更新CSS以使用基于类的深色模式:
css
/* 替换@media (prefers-color-scheme: dark)为: */
.dark {
  --color-background: hsl(222.2 84% 4.9%);
  /* ... 其余深色主题变量 */
}

Troubleshooting

故障排除

"tailwind.config.js created by shadcn CLI"

"shadcn CLI生成了tailwind.config.js"

Delete it. The CLI sometimes generates v3 configs. Run:
bash
rm tailwind.config.js tailwind.config.ts
删除该文件。CLI有时会生成v3配置。执行:
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
  1. 检查
    globals.css
    是否已在布局文件中导入
  2. 确认
    @import "tailwindcss"
    位于文件顶部
  3. 确保
    @theme
    块包含所有必需的变量

Type errors with components

组件类型错误

Run:
bash
bun add -D @types/react @types/react-dom
执行:
bash
bun add -D @types/react @types/react-dom

cn() utility not found

cn()工具函数未找到

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));
}
创建
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, run the Tailwind v4 validator:
bash
python3 ~/.claude/skills/tailwind4-validator/scripts/validate.py --root . --verbose
This ensures no v3 patterns were accidentally introduced.
配置完成后,运行Tailwind v4验证工具:
bash
python3 ~/.claude/skills/tailwind4-validator/scripts/validate.py --root . --verbose
这将确保没有意外引入v3模式的配置。