tailwind-v4-shadcnui

star 88

Set up Tailwind v4 with shadcn/ui using @theme inline pattern and CSS variable architecture. Includes component composition patterns, accessibility guidelines, and React Hook Form integration. Use when: initializing React projects with Tailwind v4, setting up shadcn/ui dark mode, composing/extending components, implementing forms, ensuring accessibility, or fixing colors not working, theme not applying, CSS variables broken, tw-animate-css errors, or migrating from v3.

blockmatic By blockmatic schedule Updated 1/19/2026

name: Tailwind v4 + shadcn/ui description: | Set up Tailwind v4 with shadcn/ui using @theme inline pattern and CSS variable architecture. Includes component composition patterns, accessibility guidelines, and React Hook Form integration.

Use when: initializing React projects with Tailwind v4, setting up shadcn/ui dark mode, composing/extending components, implementing forms, ensuring accessibility, or fixing colors not working, theme not applying, CSS variables broken, tw-animate-css errors, or migrating from v3.

Skill: shadcn

Scope

  • Applies to: Tailwind v4 with shadcn/ui setup, CSS variable architecture, dark mode, theme configuration, component composition patterns, accessibility, form integration
  • Does NOT cover: Tailwind v3, PostCSS configuration

Assumptions

  • Tailwind CSS v4+
  • shadcn/ui latest
  • Vite (use @tailwindcss/vite plugin)
  • React 18+ or Next.js 14+
  • TypeScript 5+

Principles

  • Use @theme inline to map CSS variables to Tailwind tokens
  • Use hsl() wrapper for color values in :root and .dark
  • Set "tailwind.config": "" in components.json (empty for v4)
  • Delete tailwind.config.ts if it exists (v4 uses CSS-based config)
  • Use @tailwindcss/vite plugin (not PostCSS)
  • Use cn() utility for conditional classes
  • Semantic colors automatically adapt to dark mode (no dark: variants needed)
  • Use @plugin directive for plugins (not @import or require())
  • Compose complex components from smaller shadcn primitives
  • Extend components via wrapper pattern (don't modify originals)
  • Use CVA (class-variance-authority) for variant systems
  • Always use forwardRef for form-compatible components
  • Leverage Radix UI primitives for built-in accessibility

Constraints

MUST

  • Wrap color values with hsl() in :root and .dark
  • Use @theme inline to map all CSS variables
  • Set "tailwind.config": "" in components.json
  • Delete tailwind.config.ts if it exists
  • Use @tailwindcss/vite plugin

SHOULD

  • Use semantic color tokens (--background, --foreground, etc.)
  • Use cn() utility for conditional classes
  • Use @plugin directive for plugins
  • Compose components from smaller shadcn primitives
  • Use wrapper pattern to extend components (don't modify originals)
  • Use CVA for variant systems in custom components
  • Use forwardRef for components that need ref forwarding
  • Test accessibility with keyboard navigation and screen readers
  • Use Radix UI primitives for complex interactions (dialogs, dropdowns, etc.)
  • Provide ARIA labels for icon-only buttons and interactive elements

AVOID

  • Putting :root or .dark inside @layer base
  • Using .dark { @theme { } } pattern (v4 doesn't support nested @theme)
  • Double-wrapping colors (hsl(var(--background)) in body)
  • Using tailwind.config.ts for theme colors
  • Using @apply directive (deprecated in v4)
  • Using dark: variants for semantic colors
  • Using @import or require() for plugins (use @plugin)
  • Modifying base shadcn components directly (use wrapper pattern)
  • Building custom dropdowns/dialogs from scratch (use Radix primitives)
  • Relying on color alone for state indication
  • Skipping accessibility testing

Interactions

Patterns

CSS Variable Setup

/* src/index.css */
@import "tailwindcss";

@theme inline {
  --color-background: var(--background);
  --color-foreground: var(--foreground);
}

:root {
  --background: hsl(0 0% 100%);
  --foreground: hsl(222.2 84% 4.9%);
}

.dark {
  --background: hsl(222.2 84% 4.9%);
  --foreground: hsl(210 40% 98%);
}

Vite Configuration

// vite.config.ts
import tailwindcss from '@tailwindcss/vite'

export default defineConfig({
  plugins: [react(), tailwindcss()],
})

Components Config

{
  "tailwind": {
    "config": "",
    "css": "src/index.css",
    "baseColor": "slate",
    "cssVariables": true
  }
}

See Templates (including Component Extension) and Architecture for complete setup.

References

Resources

Install via CLI
npx skills add https://github.com/blockmatic/basilic --skill tailwind-v4-shadcnui
Repository Details
star Stars 88
call_split Forks 11
navigation Branch main
article Path SKILL.md
More from Creator