agentsclimarketplace

Tailwind v4 shadcn setup

Skill S3YED/appie-kit/skills/design/tailwind-v4-shadcn-setup

Set up Tailwind CSS v4 + shadcn/ui for a new Next.js SaaS project in 2026. Covers CSS-first @theme configuration, OKLCH colors, tw-animate-css, container queries, RSC optimization, and all critical gotchas.From its SKILL.md

Install
npx -y skills add S3YED/appie-kit --skill tailwind-v4-shadcn-setup

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 6 stars6 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

SKILL.md

7.9 KB, ~2.6k tokens by cl100k_base, as published. Nobody here has run it

Tailwind CSS v4 + shadcn/ui Setup for AI Agents

Use this skill when setting up a new Next.js project with Tailwind CSS v4 and shadcn/ui, or when writing code for one. It encodes all the critical gotchas that differ from Tailwind v3.

Quick Setup

# 1. Create Next.js project
npx create-next-app@latest my-app --typescript --tailwind --app

# 2. shadcn/ui init (auto-detects Tailwind v4)
npx shadcn@latest init

# 3. Add core components
npx shadcn@latest add button card input dialog tabs select form

# 4. Install tw-animate-css (replaces tailwindcss-animate)
npm install tw-animate-css

globals.css Template

This is the canonical globals.css for Tailwind v4 + shadcn/ui:

@import "tailwindcss";
@import "tw-animate-css";

@custom-variant dark (&:is(.dark *));

@theme inline {
  --radius-sm: calc(var(--radius) - 4px);
  --radius-md: calc(var(--radius) - 2px);
  --radius-lg: var(--radius);
  --radius-xl: calc(var(--radius) + 4px);

  --color-background: var(--background);
  --color-foreground: var(--foreground);
  --color-card: var(--card);
  --color-card-foreground: var(--card-foreground);
  --color-primary: var(--primary);
  --color-primary-foreground: var(--primary-foreground);
  --color-secondary: var(--secondary);
  --color-secondary-foreground: var(--secondary-foreground);
  --color-muted: var(--muted);
  --color-muted-foreground: var(--muted-foreground);
  --color-accent: var(--accent);
  --color-accent-foreground: var(--accent-foreground);
  --color-destructive: var(--destructive);
  --color-border: var(--border);
  --color-ring: var(--ring);
  --color-input: var(--input);
  --color-chart-1: var(--chart-1);
  --color-chart-2: var(--chart-2);
  --color-chart-3: var(--chart-3);
  --color-chart-4: var(--chart-4);
  --color-chart-5: var(--chart-5);
}

:root {
  --background: oklch(1 0 0);
  --foreground: oklch(0.145 0 0);
  --card: oklch(1 0 0);
  --card-foreground: oklch(0.145 0 0);
  --primary: oklch(0.205 0 0);
  --primary-foreground: oklch(0.985 0 0);
  --secondary: oklch(0.96 0.01 264);
  --secondary-foreground: oklch(0.205 0 0);
  --muted: oklch(0.96 0.01 264);
  --muted-foreground: oklch(0.46 0.02 264);
  --accent: oklch(0.96 0.01 264);
  --accent-foreground: oklch(0.205 0 0);
  --destructive: oklch(0.53 0.22 27);
  --destructive-foreground: oklch(0.985 0 0);
  --border: oklch(0.91 0.01 264);
  --input: oklch(0.91 0.01 264);
  --ring: oklch(0.205 0 0);
  --chart-1: oklch(0.55 0.22 250);
  --chart-2: oklch(0.63 0.18 170);
  --chart-3: oklch(0.45 0.14 40);
  --chart-4: oklch(0.68 0.19 300);
  --chart-5: oklch(0.58 0.16 10);
  --radius: 0.5rem;
}

.dark {
  --background: oklch(0.145 0 0);
  --foreground: oklch(0.985 0 0);
  --card: oklch(0.145 0 0);
  --card-foreground: oklch(0.985 0 0);
  --primary: oklch(0.922 0 0);
  --primary-foreground: oklch(0.205 0 0);
  --secondary: oklch(0.26 0.02 264);
  --secondary-foreground: oklch(0.985 0 0);
  --muted: oklch(0.26 0.02 264);
  --muted-foreground: oklch(0.64 0.02 264);
  --accent: oklch(0.26 0.02 264);
  --accent-foreground: oklch(0.985 0 0);
  --destructive: oklch(0.55 0.22 27);
  --destructive-foreground: oklch(0.985 0 0);
  --border: oklch(0.26 0.02 264);
  --input: oklch(0.26 0.02 264);
  --ring: oklch(0.84 0.01 264);
  --chart-1: oklch(0.65 0.22 250);
  --chart-2: oklch(0.70 0.18 170);
  --chart-3: oklch(0.68 0.14 40);
  --chart-4: oklch(0.72 0.19 300);
  --chart-5: oklch(0.65 0.16 10);
}

/* Override with your brand colors */
:root {
  --primary: oklch(0.55 0.22 250);        /* your brand blue */
  --primary-foreground: oklch(0.98 0 0);   /* white text on primary */
  --radius: 0.5rem;
}
.dark {
  --primary: oklch(0.70 0.18 250);         /* lighter for dark mode */
  --primary-foreground: oklch(0.10 0 0);   /* dark text on primary */
}

components.json Template

{
  "$schema": "https://ui.shadcn.com/schema.json",
  "style": "new-york",
  "rsc": true,
  "tsx": true,
  "tailwind": {
    "config": "",
    "css": "src/styles/globals.css",
    "baseColor": "neutral",
    "cssVariables": true,
    "prefix": ""
  },
  "iconLibrary": "lucide",
  "aliases": {
    "components": "@/shared/components",
    "utils": "@/shared/utils",
    "ui": "@/shared/components/ui",
    "lib": "@/lib",
    "hooks": "@/shared/hooks"
  }
}

Container Queries Pattern

Use container queries for truly reusable components:

// Parent — establish the container
<div className="@container">  {/* or @container/card for named */}
  <ProductCard />
</div>

// Child — respond to container, not viewport
function ProductCard() {
  return (
    <div className="flex flex-col @md:flex-row @lg:gap-8">
      <Image className="w-full @md:w-1/3" />
      <div>
        <h3 className="text-lg @md:text-xl @lg:text-2xl font-bold">Title</h3>
        <span className="hidden @sm:inline text-primary">$29.99</span>
      </div>
    </div>
  );
}

Critical Gotchas

#GotchaWhat to do
1tailwindcss-animate doesn't work in v4Use tw-animate-css instead — import in CSS: @import "tw-animate-css"
2OKLCH, not HSLshadcn 2.3.0+ uses OKLCH color space. Use oklch() not hsl()
3Container parent needs measurable widthFlex columns with no explicit width break container queries
4@md:md:@md: = container query, md: = viewport media query. Don't mix
5shadcn components.json needs "rsc": trueRequired for Server Component projects
6Static shadcn components are server-safeInteractive ones (Dialog, Dropdown) include 'use client' already — no need to wrap
7Tailwind v4 is incompatible with Sass/LessCSS-first @theme directive: Sass can't parse it. Use plain CSS
8No forwardRef in componentsv4 uses React.ComponentProps<typeof Button> + data-slot attributes
9Default style deprecatedNew projects use "style": "new-york" exclusively
10Toast deprecatedUse sonner instead

Design Token Hierarchy

Brand tokens (--brand-blue-500) → Semantic tokens (--color-primary) → Component tokens (--button-bg)

Use semantic tokens in your CSS. AI agents (Claude Code, Cursor) parse CSS variables more reliably than JS config files.

@theme {
  /* Brand tokens */
  --color-brand-blue: oklch(0.55 0.22 250);
  --color-brand-green: oklch(0.63 0.18 170);

  /* Semantic tokens (map brand values) */
  --color-primary: var(--color-brand-blue);
  --color-success: var(--color-brand-green);
}

RSC Optimization

  • Server components for all static Tailwind-styled UI (no 'use client')
  • Client islands only where state/events exist
  • Variant computation server-side with class composition, not runtime
// ✅ Server Component — styling is just inert strings
function ProductCard({ title, price }: { title: string; price: number }) {
  const sizeClass = price > 100 ? 'text-xl' : 'text-base';
  return (
    <div className="rounded-lg border p-4">
      <h2 className={`font-bold ${sizeClass}`}>{title}</h2>
    </div>
  );
}

Reference Documents

  • references/research-2026-07-02.md — Full research context with source URLs, MCP server evaluation table, and all 10 AI agent gotchas in one place.

MCP Servers for Tailwind (recommended)

Install these in your Hermes/Claude config:

{
  "mcpServers": {
    "tailwindcss-docs-mcp": {
      "command": "npx",
      "args": ["-y", "tailwindcss-docs-mcp"]
    },
    "designmcp-server": {
      "command": "npx",
      "args": ["-y", "@cdej-lgtm/designmcp-server"]
    }
  }
}
  • tailwindcss-docs-mcp: Local semantic search over Tailwind docs (v3 + v4)
  • designmcp-server: shadcn/ui theming with OKLCH color science===ME:tailwind-v4-shadcn-setup

What ships with it: 1 file

2.8 KB alongside SKILL.md

references/

Keep looking

Skills are one crate of 325,949. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.