tailwind-merge

Merge Tailwind CSS classes without style conflicts

Library
npm
v3.7.0
5,692 stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum. How we score it →
86 /100 Excellent
Development Activity 92
Maintenance 100
Community 56
Maturity 56
Momentum 40

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation. How we score it →
90 /100 Excellent
Architecture 90
Code Quality 92
Innovation 90
Learning Curve 88

tailwind-merge is a TypeScript utility that merges strings of Tailwind CSS classes and resolves conflicts between them, so that when two classes target the same styling concern the last one specified wins instead of both being applied and silently fighting in the CSS cascade.

It ships with zero runtime dependencies, understands the full default Tailwind config out of the box, and can be extended to understand custom themes, plugins, and class groups via extendTailwindMerge and mergeConfigs.

What You Get

  • A single twMerge() function that merges any number of class strings/arrays and strips out conflicting Tailwind utilities.
  • A twJoin() helper for conditionally joining class names (a typed subset of clsx) when conflict resolution isn’t needed.
  • extendTailwindMerge, createTailwindMerge, and mergeConfigs for teaching the merge logic about a customized Tailwind theme or plugin classes.
  • Full TypeScript types for every export, plus a legacy ./es5 bundle for older browser targets.

Common Use Cases

  • Accepting an overridable className prop in a reusable component.
  • Merging variant classes generated by cva or tailwind-variants in a design system.
  • Resolving conditionally-applied Tailwind classes in state-driven UI.
  • Supporting a customized Tailwind theme with non-default spacing/color scales.

Under The Hood

Architecture — twMerge (src/lib/tw-merge.ts) is createTailwindMerge(getDefaultConfig): a factory in src/lib/create-tailwind-merge.ts that lazily builds its config and an LRU cache (src/lib/lru-cache.ts) on first call, then swaps its internal functionToCall reference to a fast cached path for every call after — avoiding config-parsing cost when twMerge is never invoked. The actual merge happens in mergeClassList (src/lib/merge-classlist.ts): the input is first joined by twJoin (a typed clsx subset, src/lib/tw-join.ts), then class names are walked right-to-left, each parsed by parseClassName (src/lib/parse-class-name.ts) into modifiers, base class, important-flag, and postfix-modifier position while tracking bracket/paren depth for arbitrary values like bg-[#B91C1C]. Each class resolves to a classGroupId via config-utils’ class-group matching (built from src/lib/default-config.ts and src/lib/validators.ts); a class is dropped if a later class already claimed the same modifier+classGroupId conflict key, with getConflictingClassGroupIds expanding transitive conflicts (e.g. px conflicts with pl and pr).

Tech Stack — Pure TypeScript with zero runtime dependencies ("dependencies": {} in package.json); built with Rollup (scripts/rollup.config.mjs) into separate ESM/CJS/ES5 bundles exposed via package.json’s exports map (. vs ./es5); tested with Vitest 4 plus @vitest/coverage-v8 for coverage and @codspeed/vitest-plugin for benchmark-regression tracking; linted with ESLint 9’s flat config and typescript-eslint; managed as a pnpm 11 workspace (pnpm-workspace.yaml) requiring Node >=22 via devEngines.runtime.

Code Quality — 36 test files under tests/ cover arbitrary values/properties/variants, class-group conflicts, the important modifier, negative values, lazy initialization, and even a docs-examples.test.ts that runs the README’s own code samples to keep documentation honest. A dedicated typescript-compat devDependency pins an older TypeScript version to verify the shipped .d.ts declarations stay compatible. Source modules are small and single-purpose (parse-class-name.ts, merge-classlist.ts, lru-cache.ts, sort-modifiers.ts are each well under 150 lines) with inline comments justifying non-obvious performance choices, such as the “Fast path: skip sorting for empty or single modifier” branch in merge-classlist.ts.

API Design — The zero-config twMerge default covers the common case with no setup (twMerge('a', 'b')), while power users extend behavior via extendTailwindMerge, createTailwindMerge, and mergeConfigs without forking internals, and fromTheme lets custom class groups key off the consumer’s own Tailwind theme. Bundle size is treated as a first-class concern (a Bundlephobia badge in the README, a dedicated ./es5 export for legacy targets), and documentation is split into task-oriented pages (what-is-it-for, when-and-how-to-use-it, configuration, recipes, api-reference, writing-plugins) rather than one long README.

Used by 219 apps in this directory

TypeScript
63%
AGPL 3.0

undb

Databases · No Code Platforms

2,978

Self-hosted no-code database and BaaS that lets you manage structured data visually with multi-database support, formula fields, and auto-generated OpenAPI endpoints.

View details
61
Repo Health
66
Technical
65
Dependency
Built with
TypeScript 63%
Svelte 35%
Updated 2 weeks ago
Go
58%
AGPL 3.0

Unkey

Developer Tools

5,450

An open-source developer platform for API infrastructure — issue and verify API keys, enforce global rate limits, route traffic through a gateway, and get per-key analytics and audit logs.

View details
91
Repo Health
70
Technical
68
Dependency
Built with
Go 58%
TypeScript 41%
Updated 1 weeks ago
TypeScript
90%
AGPL 3.0

useSend

Developer Tools · Marketing

4,698

Self-hostable open source email platform built on Amazon SES with a full dashboard, SMTP relay, REST API, and multi-language SDKs.

View details
78
Repo Health
72
Technical
68
Dependency
Built with
TypeScript 90%
Updated 1 months ago
Python
73%
Apache 2.0

Unsloth

AI Assistants · AI Development

76,886

Run and fine-tune LLMs, diffusion, audio and embedding models on your own hardware, from a native desktop app, a browser UI, or a Python library.

View details
89
Repo Health
83
Technical
70
Dependency
Built with
Python 73%
TypeScript 21%
Updated 1 weeks ago
TypeScript
72%
Apache 2.0

Valmis

AI Agents

108

A security-focused, self-hostable AI agent platform for production work — agents run in isolated containers that access credentials only through a host-side proxy, so the AI itself never sees API keys or plaintext credentials.

View details
70
Repo Health
69
Technical
74
Dependency
Built with
TypeScript 72%
Svelte 27%
Updated 1 months ago
Rust
50%
Apache 2.0

Vibe Kanban

AI Agents · AI Code Assistants · Project Management

28,209

A kanban board for planning work and dispatching Claude Code, Codex, Gemini CLI, and eight other coding agents into isolated git worktrees, then reviewing and merging their diffs from one UI.

View details
75
Repo Health
75
Technical
64
Dependency
Built with
Rust 50%
TypeScript 46%
Updated 2 weeks ago
Python
95%
AGPL 3.0

VideoHighlighter

Video Editors

138

Local AI desktop tool that scores, explains, and cuts the moments that matter in raw footage — scene, motion, audio, object, and action detection, fully offline via Ollama and Whisper.

View details
80
Repo Health
84
Technical
71
Dependency
Built with
Python 95%
Updated 1 weeks ago
TypeScript
53%
MIT

Voicebox

AI Development · Productivity · Voice AI

55,864

Clone voices, dictate anywhere, and give AI agents your voice — all locally.

View details
79
Repo Health
76
Technical
68
Dependency
Built with
TypeScript 53%
Python 35%
Updated 2 months ago
Python
56%
AGPL 3.0

VoiceStudio

Mcp · Music Audio · Voice AI

51,962

Open-source, fully local ElevenLabs alternative for voice cloning, voice design, video dubbing, dictation, transcription and audiobooks, with a local API and MCP server for agents.

View details
85
Repo Health
83
Technical
70
Dependency
Built with
Python 56%
JavaScript 23%
TypeScript 19%
Updated 6 days ago

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers