CSS-in-JS is not automatically bad.
It solved real problems:
- component-level style colocation
- theme composition
- dynamic variants
- avoiding large global stylesheets
The performance cost is that some CSS-in-JS approaches do work at runtime that static CSS does not.
That is the part teams should evaluate honestly.
Not All CSS-in-JS Is the Same
There are two broad categories:
- runtime systems that generate and inject styles in the browser
- compile-time systems that extract styles ahead of time
Those are very different performance profiles.
If your styling library generates rules during render, you are paying for that on the client. If your styles are extracted at build time, the runtime cost is much lower.
That distinction matters more than the label.
Why Static CSS Often Wins
Static CSS, whether handwritten, extracted, or utility-first, shifts more work to build time and lets the browser do what it is already good at:
- download styles once
- cache them
- apply them without a JavaScript styling engine in the hot path
That is one reason Tailwind can feel operationally simple in large applications. The trade-off is different ergonomics, not magic.
The React Angle
Runtime style injection can also complicate rendering because style insertion has ordering requirements.
That is why React exposes useInsertionEffect for CSS-in-JS library authors. It is not evidence that CSS-in-JS is broken. It is evidence that runtime styling has coordination costs that static CSS largely avoids.
A More Useful Decision Rule
Choose runtime CSS-in-JS when:
- styling is highly dynamic
- the team strongly values those ergonomics
- the performance budget can absorb the client-side work
Choose static or extracted CSS when:
- startup cost matters
- mobile devices are a key constraint
- the design system is mostly known at build time
This is one place where "zero-runtime" is a meaningful property, not just a marketing phrase.
Tailwind Is One Valid Answer
Tailwind is not better because it is fashionable. It is useful because it turns a lot of style decisions into build-time output and predictable class strings.
If that fits the team, it is a solid trade.
If it does not, extracted CSS modules or other compile-time approaches can give you similar runtime advantages without adopting utility classes everywhere.
Further Reading