Introduction
tailwind-merge is a utility function that merges multiple Tailwind CSS class strings while intelligently resolving conflicts. When two classes target the same CSS property, the last one wins. This is essential for component libraries where parent components need to override child styles without leftover conflicting classes.
What tailwind-merge Does
- Merges multiple class strings and removes conflicting Tailwind utilities
- Understands Tailwind class groups so px-2 is correctly overridden by p-3
- Handles arbitrary values, modifiers, and responsive prefixes
- Supports Tailwind v3 and v4 class syntax out of the box
- Provides configuration API for custom utility classes and plugins
Architecture Overview
tailwind-merge parses each class string into tokens, identifies the class group each token belongs to (e.g., padding, margin, background-color), and keeps only the last token for each group. A LRU cache stores recent merge results for performance. The class group definitions are generated from Tailwind CSS configuration, and custom groups can be registered for plugins or custom utilities.
Self-Hosting & Configuration
- Install via npm:
npm install tailwind-merge - Import and call:
twMerge('class-a', 'class-b') - Configure for custom Tailwind plugins using
extendTailwindMerge - Pair with clsx for conditional + conflict-free class merging
- Cache size defaults to 500 entries; adjustable via config
Key Features
- Correctly handles all Tailwind utility class conflicts including spacing, colors, and typography
- Supports arbitrary values like bg-[#123456] and responsive/state modifiers
- LRU cache ensures fast repeated merges with minimal memory usage
- Extensible for custom Tailwind plugins and utility definitions
- Tree-shakeable ESM module with full TypeScript support
Comparison with Similar Tools
- clsx / classnames — concatenates classes but does not resolve conflicts; complementary, not a replacement
- cn() helper (shadcn/ui) — combines clsx and tailwind-merge in a single utility function
- twJoin — included in tailwind-merge for simple joining without conflict resolution
- Tailwind CSS @apply — compile-time class application; does not help with runtime dynamic classes
- cva (class-variance-authority) — manages component variants; often used alongside tailwind-merge
FAQ
Q: When do I need tailwind-merge vs. plain clsx? A: Use tailwind-merge when components accept className props that may conflict with internal styles. Use clsx alone when you only need conditional class construction without conflict resolution.
Q: Does it work with Tailwind v4? A: Yes. tailwind-merge supports Tailwind v4 syntax including the new color and spacing utilities.
Q: What is the cn() pattern from shadcn/ui?
A: It combines clsx and twMerge: const cn = (...inputs) => twMerge(clsx(inputs)). This lets you conditionally build class strings and resolve Tailwind conflicts in one call.
Q: Can I use it with CSS Modules or other styling solutions? A: tailwind-merge is designed specifically for Tailwind CSS class strings. It will not provide value for non-Tailwind class names.