Skip to main content
BlueForge
EngineeringSeptember 17, 20263 min read

Tailwind Compiled Almost Nothing

Kristian Mandrup

Founder & CEO

RoomCraft's stylesheet was compiling to almost nothing, and the build was perfectly happy about it.

What the output actually contained

The application's global stylesheet still used Tailwind's v3 entry points while the project had moved to v4. The build did not fail. It emitted:

  • 0 --color-* variables
  • no bg-blue-* utilities
  • no text-gray-* utilities

Every utility in the application was unstyled. The page rendered — the markup was all there, the classes were all there — and the stylesheet that was supposed to interpret them contained almost none of the rules.

The dark theme that could never have worked

The more interesting consequence is what happened to the theme toggle. In v4, dark: compiles to a prefers-color-scheme media query unless a variant strategy says otherwise. With the v3 entry points in place, the stylesheet had no .dark rules and no variables for a toggle to switch.

So the theme control could not have worked no matter what it wrote to the DOM. Users could toggle it, the state changed, the class changed — and nothing on the page could respond, because the CSS that would have responded had never been generated. The bug looked like a broken toggle. It was actually an empty stylesheet.

After the fix: 77 KB of CSS, 338 colour variables, 565 .dark rules.

Three more defects underneath it

Once the stylesheet was real, the rest of the front end could finally be seen:

  • The toggle offered three states, and there was no pre-paint script at all — so a returning visitor got the default theme and then a flash. Only light and dark are ever written now, in a blocking script in the head.
  • The 404 page was invisible in dark mode.
  • The site header's link list was hidden md:flex with nothing in its place — so below 768 pixels, on every phone, the marketing site had no navigation at all. Not hidden behind a menu: absent.
  • On a 375×667 viewport the canvas rendered 200 pixels wide inside a 373-pixel container, because a width calculation clamped to a floor that was larger than the space available.

None of those was caused by the stylesheet. All four were hidden by it: when nothing is styled, a missing menu and an invisible page look the same as an ugly one.

The same class, fleet-wide

The same failure mode hit our office platform: a shared header whose navigation was display: none at every width, in all ten apps in production. There, the cause was v4's source auto-detection skipping pnpm's node_modules symlinks — the utility class was never scanned, so it was never generated.

That is the family: a CSS build that produces a partial stylesheet, exits zero, and reports nothing. Which is why we now assert on the output rather than on the exit code — count the colour variables, count the variant rules, and fail the build when the stylesheet is thinner than it should be. A green build that produced no CSS is the most expensive kind of green there is.

Stay in the Loop

Get early access to our products and be the first to know when we launch.

Join the Waiting List