patterncsstailwindTip
clsx/cn utility pattern for conditional Tailwind classes
Viewed 0 times
clsxcnconditional classesclassnamesvariantpattern
Problem
Conditionally applying Tailwind classes in JSX leads to messy template literals with ternaries and string concatenation that are hard to read and error-prone.
Solution
Use
clsx (or clsx + tailwind-merge as cn) for clean conditional class composition:npm install clsx tailwind-merge// utils/cn.ts — the canonical cn utility
import { clsx, type ClassValue } from 'clsx';
import { twMerge } from 'tailwind-merge';
export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs));
}
// Usage in components
import { cn } from '@/utils/cn';
function Alert({ variant, className }) {
return (
<div className={cn(
'rounded-lg border p-4',
variant === 'error' && 'border-red-500 bg-red-50 text-red-800',
variant === 'success' && 'border-green-500 bg-green-50 text-green-800',
className // consumer override, conflicts resolved by twMerge
)}>
);
}Why
clsx handles the conditional logic cleanly (accepting objects, arrays, falsy values), and twMerge resolves Tailwind-specific conflicts. Together they cover all cases.
Gotchas
- Without twMerge, conflicting classes from the variant and className prop will both be in the DOM.
- The cn pattern is so common that shadcn/ui, Radix, and most modern React starters include it as a project utility.
- clsx is a lighter alternative to classnames — prefer it for Tailwind projects.
Context
When conditionally applying classes in React, Vue, or Svelte components.
Revisions (0)
No revisions yet.