Agent Skills: shadcn/ui Setup

Set up shadcn/ui component library with Tailwind CSS v4 configuration. Handles installation, initialization, theme configuration, and common component setup. Use when starting a new Next.js/React project that needs a component library.

UncategorizedID: shipshitdev/library/shadcn-setup

Install this agent skill to your local

pnpm dlx add-skill https://github.com/shipshitdev/library/tree/HEAD/bundles/frontend/skills/shadcn-setup

Skill Files

Browse the full folder contents for shadcn-setup.

Download Skill

Loading file tree…

bundles/frontend/skills/shadcn-setup/SKILL.md

Skill Metadata

Name
shadcn-setup
Description
>-

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

# 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

{
  "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:

# 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

{
  "$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

// 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

# Using bunx (recommended with bun)
bunx shadcn@latest add button

# Multiple components
bunx shadcn@latest add card dialog dropdown-menu

Using Components

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:

// 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:

/* 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:

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:

bun add -D @types/react @types/react-dom

cn() utility not found

Create src/lib/utils.ts:

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:

# 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