tailwind-react

SKILL.md

Critical Patterns

Class Merging (REQUIRED)

import { clsx } from 'clsx';
import { twMerge } from 'tailwind-merge';

// ✅ ALWAYS: Use cn() utility for class merging
function cn(...inputs: ClassValue[]) {
  return twMerge(clsx(inputs));
}

// Usage
<div className={cn(
  "base-classes",
  condition && "conditional-classes",
  className
)} />

Component Variants (REQUIRED)

import { cva, type VariantProps } from 'class-variance-authority';

// ✅ Use CVA for variant management
const buttonVariants = cva(
  "inline-flex items-center rounded-md font-medium transition-colors",
  {
    variants: {
      variant: {
        primary: "bg-blue-600 text-white hover:bg-blue-700",
        secondary: "bg-gray-100 text-gray-900 hover:bg-gray-200",
        ghost: "hover:bg-gray-100",
      },
      size: {
        sm: "h-8 px-3 text-sm",
        md: "h-10 px-4 text-base",
        lg: "h-12 px-6 text-lg",
      },
    },
    defaultVariants: {
      variant: "primary",
      size: "md",
    },
  }
);

interface ButtonProps extends VariantProps<typeof buttonVariants> {
  children: React.ReactNode;
}

function Button({ variant, size, children }: ButtonProps) {
  return (
    <button className={buttonVariants({ variant, size })}>
      {children}
    </button>
  );
}

Decision Tree

Need dynamic classes?      → Use clsx/cn utility
Need variants?             → Use CVA
Need conditional?          → Use clsx with conditions
Need to override?          → Use tailwind-merge

Code Examples

Conditional Classes

<button
  className={cn(
    "px-4 py-2 rounded",
    isActive ? "bg-blue-600 text-white" : "bg-gray-200",
    disabled && "opacity-50 cursor-not-allowed"
  )}
>
  Click me
</button>
Weekly Installs
5
First Seen
Jan 26, 2026
Installed on
github-copilot4
cline3
gemini-cli3
codex3
continue3
cursor3