At a recent Q&A Dan Abramov talked of the React core team becoming more opinionated about styling approaches:
“We used to be very unopinionated about styling. We’re getting a few more opinions now because there are a few more constraints like streaming server rendering, server components. We start caring a bit more about performance. Overall we’re thinking for dynamic stuff just use inline styles. For things that don’t change use something that compiles to CSS so that it doesn’t have extra runtime costs. A lot of these approaches with runtimes are really expensive.”
This statement reiterated what had already been said by Sebastian Markbage.
CSS-in-JS solutions with a runtime include libraries like Emotion and Styled Components, which still remain popular.
Their impact on performance is a topic that Alex Russell, a Product Manager on Microsoft Edge, has harped on about for years, referring to the approach as a "full-on catastrophe", writing:
"At load time we can parallelise parsing of CSS, JS, and HTML. But when you stuff your CSS into JS, it means we need to parse & run JS to get rules into the doc."
Facebook/Meta had announced plans to open source their own zero-runtime CSS-in-JS tool, but that was several years ago so may never happen. There are several open source alternatives. An engineer at Airbnb recently blogged about that companies move from a runtime CSS-in-JS library to Linaria, a zero runtime option.
There’s also Vanilla Extract from Mark Dalgleish (a co-creator of CSS Modules), another zero runtime tool that involves writing styles in TypeScript and compiling them to static CSS files at build time. In my opinion the idea of writing styles in Typescript sounds appalling, but it’s not without its fans.
It’s been Tailwind, a JIT (Just In Time) compiled atomic CSS library (with no client-side runtime), that has really taken off, with fifty eight thousand GitHub stars at the time of writing.
Or you could just write CSS. With CSS itself getting more powerful with features like
@layer, it’s fair to say that some of the original rationale for CSS-in-JS is less relevant today. Importing a SASS or CSS file at the top of a JSX file still works well for me. As someone that spends time designing in the browser I’d be happy to never see an unreadable machine-generated class like
.atm_5tsdf ever again.