ShopperCove
Menu
All writingBlogTopicsCategoriesAboutRSS
Blog
Categories
Observability & SRE62All categories
About

Plate 91

  1. Blog

tailwind-merge vs clsx: 8.6 KB vs 264 B

Aditya Challa·5 October 2026·4 min read

Hands-on
On this page
  1. What I tested
  2. How much smaller is clsx?
  3. Does merge speed matter?
  4. Do the APIs behave the same?
  5. Which one should you pick?
  6. Sources
  7. Related

I bundled the two className helpers on this box: tailwind-merge 3.7.0 came out at 8,561 bytes gzip, while clsx 2.1.1 came out at 264 bytes. On 200k mixed-arg builds, clsx ran about 18.6M–20.0M ops/s versus about 4.4M–4.5M for twMerge, and only twMerge dropped conflicting Tailwind utilities.

Short answer: keep clsx (or clsx + a merge layer) when you only need conditional class strings. Reach for tailwind-merge when conflicting utilities like px-2 vs px-4 must resolve to one winner in the final class list. No affiliate links in this post.

What I tested

  • Machine: 8 vCPU Intel Xeon / 15 GB RAM shared Linux cloud box, tested 6 Oct 2026 about 02:22 IST.
  • Versions: tailwind-merge 3.7.0, clsx 2.1.1, Node 22.20.0, esbuild 0.28.2 browser ESM minify + gzip -9.
  • Inputs: string + false/null conditionals + conflicting Tailwind tokens. Speed: 200,000 builds × 9-round median, two order-reversed runs. Scripts in /workspace/bench-tailwind-merge-clsx/.
  • Findings: twMerge 27,407/8,561 B vs clsx 412/264 B. Medians: twMerge 44.881 / 45.925 ms (file1) and 45.011 / 45.379 ms (file2); clsx 10.740 / 10.635 ms and 10.688 / 9.997 ms (~4× more ops/s). Conflict: twMerge("px-2 px-4") → "px-4"; clsx keeps both. Disk ~1.0 MB vs ~8 KB.
  • One surprise: twJoin still concatenates like clsx (px-2 px-4 stayed both classes); only twMerge applies the conflict group rules.
  • Not tested: createTailwindMerge custom configs, RTL variants, Tailwind v4 token tables beyond the default, CSS Modules composition, or Rollup/webpack tree-shake matrices.

How much smaller is clsx?

Build (esbuild browser minify)Minifiedgzip -9
tailwind-merge27,407 B8,561 B
clsx412 B264 B

About 32× smaller gzip for clsx. Pair this with the older class helper lab clsx vs classnames. Track client cost the same way as size-limit vs bundlesize. Tailwind-adjacent CSS tooling sits next to UnoCSS vs Tailwind and Lightning CSS vs PostCSS.

Does merge speed matter?

200k mixed builds (median of 9, 2 order-reversed runs)tailwind-mergeclsx
Order twMerge then clsx (ms / ops/s, file 1)44.881 / ~4.46M10.740 / ~18.6M
Order clsx then twMerge (ms / ops/s, file 1)45.925 / ~4.35M10.635 / ~18.8M
File 2 repeats45.011 / 45.37910.688 / 9.997

clsx stayed about 4× cheaper per call. That gap only matters in hot class rebuild loops; for typical React renders the conflict-resolution behavior usually wins the decision. Tiny string helpers in a nearby lane show up in picocolors vs chalk.

Do the APIs behave the same?

Topictailwind-merge 3.7.0clsx 2.1.1
Conditional false/nulldrops themdrops them
"px-2 px-4""px-4""px-2 px-4"
Multi-arg conflict (bg-red + bg-blue)last wins (bg-blue-500)keeps both
Join without conflict rulestwJoin keeps bothn/a (clsx is join)

They are not substitutes. clsx builds the string; twMerge also understands Tailwind conflict groups. Lint/format stacks that often ship with the same frontend decision sit next to Biome vs ESLint + Prettier. Asset pipelines nearby: SVGO vs SVGR.

Which one should you pick?

SituationMy pick
Conditional classes only, no Tailwind conflictsclsx
Smallest browser helper on this boxclsx
Tailwind utilities that override each othertailwind-merge
Already on clsx, need conflict dropsclsx + twMerge together
Image/asset minify instead of class stringssee sharp vs jimp​

Bottom line: tailwind-merge 3.7.0 was 8,561 B gzip versus 264 B for clsx 2.1.1, clsx ran about 4× more ops/s, and only twMerge turned "px-2 px-4" into "px-4". Who should not drop twMerge: any Tailwind UI that relies on later classes winning conflicts. Who should not add it: projects that never emit conflicting utilities and care about every kilobyte.

How this was made: I installed both packages on the ShopperCove box, measured esbuild browser bundles, timed 200k class builds in two order-reversed runs, and compared conflict/conditional/twJoin behavior. The JSON results sit next to the scripts. The write-up was drafted with AI help and checked against that output.

Sources

  • https://github.com/dcastil/tailwind-merge
  • https://github.com/lukeed/clsx
  • https://www.npmjs.com/package/tailwind-merge
  • https://www.npmjs.com/package/clsx

Related

  • https://www.shoppercove.com/blog/clsx-vs-classnames
  • https://www.shoppercove.com/blog/size-limit-vs-bundlesize
  • https://www.shoppercove.com/blog/unocss-vs-tailwind
  • https://www.shoppercove.com/blog/lightningcss-vs-postcss
  • https://www.shoppercove.com/blog/picocolors-vs-chalk
  • https://www.shoppercove.com/blog/biome-vs-eslint-prettier
  • https://www.shoppercove.com/blog/svgo-vs-svgr
  • https://www.shoppercove.com/blog/sharp-vs-jimp
tailwind-mergeclsxtailwind cssbundle sizeperformancereactfrontend

Lab evidence

What I found running this

Hands-on on ShopperCove box 6 Oct 2026 ~02:22 IST (8 vCPU Intel Xeon / 15 GB shared Linux, Node 22.20.0). tailwind-merge 3.7.0 vs clsx 2.1.1, esbuild 0.28.2 browser ESM minify + gzip -9. Size: 27,407/8,561 B vs 412/264 B. Speed 200k mixed builds x 9-round median, order-reversed: twMerge ~44.9-45.9 ms (~4.4M ops/s) vs clsx ~10.0-10.7 ms (~18.6-20.0M). Conflict: twMerge px-2 px-4 -> px-4; clsx keeps both. Disk ~1.0 MB vs ~8 KB. Not tested: createTailwindMerge, RTL, Tailwind v4 custom tables. No affiliate.

Notes when a lab post goes up

Occasional email for new hands-on reviews. No sequence and no sponsors.

Related links

  • Plate 78

    Clsx vs classnames: 294 B vs 857 B Gzip

    5 Oct 2026

  • Plate 66

    Jotai vs Zustand: 0.15 ms vs 0.17 ms per Update

    5 Oct 2026

  • Plate 38

    TanStack Query vs SWR: 10.4 KB vs 5.6 KB Gzip

    5 Oct 2026

On this page

  1. What I tested
  2. How much smaller is clsx?
  3. Does merge speed matter?
  4. Do the APIs behave the same?
  5. Which one should you pick?
  6. Sources
  7. Related
All writingBlogCategoriesTopicsAboutPrivacyRSS

© 2026 ShopperCove