tailwind-design-system
giuseppe-trisciuoglio/developer-kit
Build consistent UI component libraries with Tailwind CSS v4.1+ and shadcn/ui design tokens.
What is tailwind-design-system?
Skill for orchestrating a centralized Design System using Tailwind CSS and shadcn/ui. Use this when defining design tokens, configuring theming with CSS variables, wrapping shadcn/ui components into design system primitives, or establishing a token-driven component library. Complements tailwind-css-patterns (utility styling) and shadcn-ui (individual components) by focusing on system-level consistency.
- Define design tokens (colors, typography, spacing, radius, shadows) as CSS variables in globals.css
- Configure theming infrastructure with light/dark mode and multi-theme support using CSS variables and @theme directives
- Wrap shadcn/ui components into design system primitives with enforced constraints and variant mapping
- Bridge CSS variables to Tailwind utilities for consistent token usage across the application
- Validate design token completeness and ensure all components use design system colors
- Support oklch color format for perceptually uniform color palettes
How to install tailwind-design-system
npx skills add https://github.com/giuseppe-trisciuoglio/developer-kit --skill tailwind-design-system- Tailwind CSS v4.1+ installed (npx tailwindcss --version)
- shadcn/ui CLI initialized (npx shadcn@latest init)
- Node.js project with React and TypeScript support
How to use tailwind-design-system
- 1.Run npx tailwindcss --version and npx @tailwindcss/vite@latest init to set up Tailwind v4
- 2.Initialize shadcn/ui with npx shadcn@latest init and install core components (button, card, input)
- 3.Create src/app/globals.css with @tailwind directives and define design tokens in :root and .dark using oklch color format
- 4.Add @theme inline block to bridge CSS variables to Tailwind utilities (e.g., --color-primary: var(--primary))
- 5.Create wrapper components in src/components/ds/ that map design system variants to shadcn/ui variants
- 6.Validate token completeness by running grep checks to ensure all required tokens (primary, background, foreground, etc.) are defined in both light and dark modes
Use cases
- Setting up a new design system from scratch with Tailwind CSS v4.1+ and shadcn/ui
- Migrating from JavaScript-based Tailwind config to CSS-first configuration
- Creating multi-theme support beyond light/dark (e.g., brand themes like ocean, forest)
- Wrapping shadcn/ui Button, Card, Input components into constrained design system primitives
- Establishing color palettes with semantic tokens (primary, secondary, destructive, warning)
- Design system architects building component libraries
- Full-stack developers establishing design consistency across applications
- Teams migrating to Tailwind CSS v4.1+ with shadcn/ui
- Product teams needing multi-theme or white-label support
tailwind-design-system FAQ
tailwind-css-patterns covers utility-first styling and responsive design; shadcn-ui covers individual component installation. This skill focuses on system-level orchestration: design tokens, theming infrastructure, component wrapping patterns, and consistency across the entire application.
oklch provides perceptual uniformity, meaning colors with the same lightness value appear equally bright to the human eye. This ensures consistent visual hierarchy across your design system. Note: verify browser compatibility if targeting older browsers.
Use @theme inline when bridging CSS variables to Tailwind utilities (e.g., --color-primary: var(--primary)). Use @theme for direct token definition. Inline is preferred for design systems that manage tokens in CSS variables.
Define tokens in :root for light mode, then redefine them in .dark selector with appropriate dark values. Always provide a dark mode value for every token to avoid missing styles. Use document.documentElement.classList.toggle('dark', isDark) to toggle the class.
Wrap components that need design system constraints (Button, Card, Input). Keep wrappers thin—only add constraints that enforce design system rules. Avoid duplicating shadcn/ui logic; pass through props and use variant mapping to maintain consistency.
Full instructions (SKILL.md)
Source of truth, from giuseppe-trisciuoglio/developer-kit.
name: tailwind-design-system description: Skill for creating and managing a Design System using Tailwind CSS and shadcn/ui. Use when defining design tokens, setting up theming with CSS variables, building a consistent UI component library, initializing a design system configuration, or wrapping shadcn/ui components into design system primitives. allowed-tools: Read, Write, Edit, Bash, Glob, Grep
Tailwind CSS & shadcn/ui Design System
Overview
Expert guide for creating and managing a centralized Design System using Tailwind CSS (v4.1+) and shadcn/ui. This skill provides structured workflows for defining design tokens, configuring themes with CSS variables, and building a consistent UI component library based on shadcn/ui primitives.
Relationship with other skills:
- tailwind-css-patterns covers utility-first styling, responsive design, and general Tailwind CSS usage
- shadcn-ui covers individual component installation, configuration, and implementation
- This skill focuses on the system-level orchestration: design tokens, theming infrastructure, component wrapping patterns, and ensuring consistency across the entire application
When to Use
- Setting up a new design system from scratch with Tailwind CSS and shadcn/ui
- Defining design tokens (colors, typography, spacing, radius, shadows) as CSS variables
- Configuring
globals.csswith a centralized theming system (light/dark mode) - Wrapping shadcn/ui components into design system primitives with enforced constraints
- Building a token-driven component library for consistent UI
- Migrating from a JavaScript-based Tailwind config to CSS-first configuration (v4.1+)
- Establishing color palettes with oklch format for perceptual uniformity
- Creating multi-theme support beyond light/dark (e.g., brand themes)
Instructions
Step 1: Initialize Design System Configuration
Run these commands to set up the project:
# Check if Tailwind is installed
npx tailwindcss --version
# For Tailwind v4 (recommended)
npx @tailwindcss/vite@latest init # or: npm install -D tailwindcss @tailwindcss/vite
# Initialize shadcn/ui CLI
npx shadcn@latest init
# Install core shadcn/ui components
npx shadcn@latest add button card input -y
Validation checkpoint: After setup, verify with:
ls src/components/ui/ # Should list installed components
cat src/app/globals.css # Should contain @tailwind directives
Step 2: Define Design Tokens
Create src/app/globals.css with your design tokens:
@tailwind base;
@tailwind components;
@tailwind utilities;
@layer base {
:root {
/* Brand Colors */
--primary: oklch(0.55 0.18 250);
--primary-foreground: oklch(0.985 0 0);
/* Semantic Colors */
--background: oklch(0.99 0 0);
--foreground: oklch(0.15 0 0);
--secondary: oklch(0.96 0.01 250);
--secondary-foreground: oklch(0.20 0 0);
/* Validation: all colors must have foreground pair */
--destructive: oklch(0.55 0.22 25);
--destructive-foreground: oklch(0.985 0 0);
}
.dark {
--primary: oklch(0.65 0.20 250);
--background: oklch(0.14 0 0);
--foreground: oklch(0.97 0 0);
--secondary: oklch(0.25 0.02 250);
}
}
Validation checkpoint: Verify tokens are valid CSS:
grep -E "^[[:space:]]*--[a-z-]+:" src/app/globals.css | wc -l
# Should return count of defined tokens (e.g., 10+)
Step 3: Configure Theming Infrastructure
Bridge CSS variables to Tailwind utilities (Tailwind v4.1+):
@theme inline {
--color-primary: var(--primary);
--color-primary-foreground: var(--primary-foreground);
--color-background: var(--background);
--color-foreground: var(--foreground);
}
Add dark mode class toggle in components/providers/theme-provider.tsx:
import { useEffect } from "react";
export function ThemeProvider({ children }: { children: React.ReactNode }) {
useEffect(() => {
const isDark = window.matchMedia("(prefers-color-scheme: dark)").matches;
document.documentElement.classList.toggle("dark", isDark);
}, []);
return <>{children}</>;
}
Validation checkpoint: Test dark mode:
document.documentElement.classList.contains("dark") // in browser console
Step 4: Wrap shadcn/ui Components
Create src/components/ds/Button.tsx:
import { Button as ShadcnButton } from "@/components/ui/button";
type DSVariant = "primary" | "secondary" | "destructive" | "ghost";
const variantMap: Record<DSVariant, "default" | "secondary" | "destructive" | "ghost"> = {
primary: "default", secondary: "secondary",
destructive: "destructive", ghost: "ghost",
};
export function Button({ variant = "primary", ...props }: { variant?: DSVariant } & React.ComponentProps<typeof ShadcnButton>) {
return <ShadcnButton variant={variantMap[variant]} {...props} />;
}
Validation checkpoint: Verify build passes:
npx tsc --noEmit src/components/ds/Button.tsx
Step 5: Validate and Document
Run the token validation script:
REQUIRED=("primary" "primary-foreground" "background" "foreground" "secondary" "secondary-foreground")
for token in "${REQUIRED[@]}"; do
grep -q "$token:" src/app/globals.css || echo "MISSING: --$token"
done
Validation checkpoint: Ensure all shadcn components use DS tokens:
grep -r "bg-primary\|text-primary\|bg-background" src/components/ds/
Examples
Adding Custom Tokens
Extend the base tokens in globals.css:
:root {
--warning: oklch(0.84 0.16 84);
--warning-foreground: oklch(0.28 0.07 46);
}
.dark {
--warning: oklch(0.41 0.11 46);
--warning-foreground: oklch(0.99 0.02 95);
}
@theme inline {
--color-warning: var(--warning);
--color-warning-foreground: var(--warning-foreground);
}
Usage: <div className="bg-warning text-warning-foreground">Warning</div>
Wrapping shadcn/ui Components as Design System Primitives
See references/component-wrapping.md for complete examples including Button, Text, and Stack primitives with full TypeScript types.
Create constrained design system components that enforce token usage. Inline example:
import { Button as ShadcnButton } from "@/components/ui/button";
export function Button({ variant = "primary", size = "md", ...props }) {
const variantMap = { primary: "default", secondary: "secondary" };
const sizeMap = { sm: "sm", md: "default", lg: "lg" };
return (
<ShadcnButton
variant={variantMap[variant]}
size={sizeMap[size]}
{...props}
/>
);
}
Multi-Theme Support
For applications requiring multiple brand themes beyond light/dark:
[data-theme="ocean"] {
--primary: oklch(0.55 0.18 230);
--primary-foreground: oklch(0.985 0 0);
}
[data-theme="forest"] {
--primary: oklch(0.50 0.15 145);
--primary-foreground: oklch(0.985 0 0);
}
const [theme, setTheme] = useState("light");
useEffect(() => {
document.documentElement.setAttribute("data-theme", theme);
}, [theme]);
Design Token Validation
Verify all required tokens are defined:
#!/bin/bash
REQUIRED=("--background" "--foreground" "--primary" "--primary-foreground")
for token in "${REQUIRED[@]}"; do
grep -q "$token:" src/styles/globals.css || echo "Missing: $token"
done
Constraints and Warnings
- oklch color format: Use oklch for perceptual uniformity. Not all browsers support oklch natively; check compatibility if targeting older browsers
- Token naming: Follow the shadcn/ui convention (
--primary,--primary-foreground) for seamless integration @theme inline vs@theme: Use@theme inlinewhen bridging CSS variables to Tailwind utilities; use@themefor direct token definition- Component wrapping: Keep wrapper components thin. Only add constraints that enforce design system rules; avoid duplicating shadcn/ui logic
- Dark mode: Always define dark mode values for every token in
:root. Missing dark tokens cause visual regressions - CSS variable scoping: Tokens defined in
:rootare global. Use[data-theme]selectors for multi-theme without conflicts - Performance: Avoid excessive CSS custom property chains. Each
var()lookup adds minimal but non-zero overhead - Tailwind v4 vs v3: The
@themedirective and@theme inlineare v4.1+ features. For v3 projects, usetailwind.config.jswiththeme.extend
Best Practices
- Single source of truth: All design tokens live in
globals.css. Never hardcode color values in components - Semantic naming: Use purpose-based names (
--primary,--destructive) not appearance-based (--blue-500,--red-600) - Foreground pairing: Every background token must have a matching
-foregroundtoken for contrast compliance - Token scale: Define a complete scale for custom palettes (50-950) to provide flexibility
- Component barrel exports: Export all DS components from a single
index.tsfor clean imports - Accessibility: Ensure all token pairs (background/foreground) meet WCAG AA contrast (4.5:1 for text, 3:1 for large text)
- Document tokens: Maintain a visual reference of all tokens for the team
- Consistent spacing: Use Tailwind's spacing scale (
gap-2,gap-4,gap-6) through DS components rather than arbitrary values
References
- Tailwind CSS v4 Theme Configuration: https://tailwindcss.com/docs/theme
- Tailwind CSS Functions and Directives: https://tailwindcss.com/docs/functions-and-directives
- shadcn/ui Theming Guide: https://ui.shadcn.com/docs/theming
- shadcn/ui Installation (Manual): https://ui.shadcn.com/docs/installation/manual
- oklch Color Space: https://oklch.com
Related skills
More from giuseppe-trisciuoglio/developer-kit and the wider catalog.

turborepo-monorepo
Comprehensive Turborepo monorepo management for TypeScript/JavaScript projects with workspace setup, task configuration, and CI/CD optimization.

typescript-docs
Generate production-ready TypeScript documentation with JSDoc, TypeDoc, and ADRs for multiple audiences.

typescript-security-review
Security audit for TypeScript/Node.js apps: XSS, injection, CSRF, JWT, CVEs, secrets exposure.

unit-test-application-events
Unit test patterns for Spring ApplicationEvent publishers and @EventListener consumers without booting the full context.

unit-test-bean-validation
Unit test Jakarta Bean Validation constraints and custom validators with JUnit 5 in isolation.

unit-test-boundary-conditions
Test boundary conditions, edge cases, and limits in Java with JUnit 5 and AssertJ patterns.