ShopperCove
Menu
All writingBlogTopicsCategoriesAboutRSS
Blog
Categories
Observability & SRE62All categories
Topics
sre111localhost lab102performance70python58javascript47bundle size36benchmarking35node.js35web development21typescript19benchmark16content creation15All topics
About
Loading article…

ShopperCove

Hands-on notes on developer tools, written after the tool has actually been run.

All writingBlogCategoriesTopicsAboutPrivacyRSS

© 2026 ShopperCove

On this page

  1. What I tested
  2. Who shipped less CSS?
  3. Is the build-time gap real?
  4. Should you move from Tailwind to UnoCSS?
  5. Sources
  6. Related
  1. Blog

UnoCSS vs Tailwind v4: Which Ships Smaller CSS?

UnoCSS 66.5.2 (presetWind3) vs Tailwind CSS 4.1.13 (@tailwindcss/vite) on Vite 7.3.6: 80 HTML cards, same utility set, minify off. CSS 10,454 B (118 selectors) vs 18,473 B (119). Warm vite build medians (7 rounds, cache cleared): Uno 749 ms vs Tailwind 416 ms. Fixture /workspace/bench-unocss-tw/.

5 October 2026·4 min read

Hands-on
On this page
  1. What I tested
  2. Who shipped less CSS?
  3. Is the build-time gap real?
  4. Should you move from Tailwind to UnoCSS?
  5. Sources
  6. Related

On 80 identical utility-class cards in a Vite 7 app, UnoCSS 66.5 emitted 10,454 bytes of CSS while Tailwind CSS v4.1 emitted 18,473 bytes for essentially the same selector count (118 vs 119). Warm production-build medians favored Tailwind: 416 ms against UnoCSS at 749 ms.

Short answer: pick UnoCSS when shipped CSS weight is the constraint; pick Tailwind v4 when build speed and the wider utility ecosystem matter more on a small page like this. 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 00:14–00:15 IST.
  • Versions: Vite 7.3.6, Tailwind CSS 4.1.13 with @tailwindcss/vite 4.1.13, UnoCSS 66.5.2 with presetWind3, Node 22.20.0. minify and cssMinify both off.
  • Fixture: /workspace/bench-unocss-tw/. 80 HTML cards sharing one utility set (flex, gaps, colors, responsive grid, dark: variants). Matching index.tw.html / index.uno.html entrypoints.
  • Timing: wall clock around local vite build per config. Dist and Vite cache cleared each round. One warm-up, then 7 interleaved timed rounds. CSS bytes and selector counts taken from dist assets.
  • Findings: CSS 10,454 B (Uno) vs 18,473 B (Tailwind), selectors 118 vs 119. Build medians 749 ms (Uno) vs 416 ms (Tailwind). Uno CSS about 43% smaller; Tailwind about 333 ms faster median.
  • One surprise: selector counts nearly matched, yet Tailwind's stylesheet stayed ~8 KB heavier — mostly preflight / scaffolding, not extra utilities.
  • Not tested: attributify mode, icons presets, codebases, Tailwind plugins, safelist explosion, SSR frameworks, Windows or macOS.

Who shipped less CSS?

Engine (80 cards, minify off)CSS bytesSelectorsVite build median
UnoCSS 66.5 + presetWind310,454 B118749 ms
Tailwind CSS 4.1 + @tailwindcss/vite18,473 B119416 ms

Same class strings in HTML, same Vite major. UnoCSS won on payload; Tailwind won on wall time for this tiny graph (4 modules transformed). If your bottleneck is transfer size on a marketing page, the 8 KB gap is the headline. If your bottleneck is iterative vite build in CI, Tailwind was quicker here.

For adjacent CSS tooling on this site, see Lightning CSS vs PostCSS and the Tailwind CSS v4 migration checklist.

Is the build-time gap real?

On this fixture, yes: median 416 ms vs 749 ms after clearing dist and the Vite cache every round. Absolute times are small because the module graph is tiny. Do not extrapolate to a 2,000-file app without re-measuring. The useful bit is the direction: Tailwind's Oxide pipeline was the faster Vite plugin path for the same utility set.

Bundle size of the JS entry was identical (1.25 kB) because both builds only logged a querySelectorAll count. The decision is about CSS output and plugin cost, not JS.

Should you move from Tailwind to UnoCSS?

SituationMy pick
Shipping a small public page where every KB countsUnoCSS
Existing Tailwind design system / UI kitStay on Tailwind v4
Need fastest Vite plugin build on a tiny graphTailwind (here)
Want attributify or icon presets in one stackEvaluate UnoCSS
Already mid Tailwind v4 migrationFinish that path; see the v4 checklist​
Comparing broader Vite tooling choices​Vite vs Parcel and Vite Plus toolchain notes​

Bottom line: UnoCSS cut CSS from 18.5 KB to 10.5 KB on the same 80 cards; Tailwind returned the green build about 333 ms sooner. Who should not switch: teams whose components, docs, and hiring already assume Tailwind class names.

How this was made: I built matching Vite configs for Tailwind v4 and UnoCSS on the ShopperCove box, cleared caches between seven interleaved production builds, compared CSS bytes and wall medians from JSON; the write-up was drafted with AI help and checked against that output.

Sources

  • 01unocss.devhttps://unocss.dev/
  • 02tailwindcss.com/docs/installation/using-vite
  • 03github.com/unocss/unocss
  • 04github.com/tailwindlabs/tailwindcss
  • 05vite.devhttps://vite.dev/

Related

  • 01shoppercove.com/blog/vite-8-3-2-renderbuilturl-bundled-dev-sourcemaps-october-2026
  • 02shoppercove.com/blog/rolldown-vs-rollup
  • 03shoppercove.com/blog/size-limit-vs-bundlesize
  • 04shoppercove.com/blog/biome-vs-eslint-prettier
unocsstailwindcssvitecss-performanceweb-developmentbuild-toolsbundle-sizebenchmarking

Lab evidence

What I found running this

Hands-on on ShopperCove box 6 Oct 2026 ~00:14–00:15 IST (8 vCPU Intel Xeon / 15 GB shared Linux, Node 22.20.0). Vite 7.3.6, Tailwind 4.1.13 + @tailwindcss/vite 4.1.13, UnoCSS 66.5.2 presetWind3. Fixture /workspace/bench-unocss-tw/: 80 identical utility cards in HTML entrypoints; minify/cssMinify false. Local vite binary; dist + node_modules/.vite cleared each run; 1 warm-up + 7 interleaved rounds. CSS 10454 B / 118 selectors (Uno) vs 18473 B / 119 (Tailwind). Build medians 749 ms vs 416 ms. Raw: /workspace/bench-unocss-tw/res-unocss-tw.json. Not tested: attributify, icon presets, @apply-heavy apps, Tailwind plugins, SSR, Windows/macOS. No affiliate.

Notes when a lab post goes up

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

Keep reading

  • find-up vs locate-path: 47 µs Sync vs 596 µs Async

    Hands-on6 Oct 20268 min read

  • c12 vs cosmiconfig: 0.58 ms vs 1.08 ms per .mjs Load

    Hands-on6 Oct 20269 min read

  • magicast vs recast: 0.65 ms vs 0.42 ms per Vite Edit

    Hands-on6 Oct 20268 min read