TLDR: The CSS-in-JS community has converged on a consistent API.
Not so long ago, a Facebook engineer compiled a list of the available CSS-in-JS methodologies. It wasn’t short:
aphrodite, babel-plugin-css-in-js, babel-plugin-pre-style, bloody-react-styled, classy, csjs, css-constructor, css-light, css-loader, css-ns, cssobj, cssx-loader, cxs, electron-css, emotion, es-css-modules, freestyler, glamor, glamorous, hiccup-css, hyperstyles, i-css, j2c, jsxstyle, linaria, nano-css, pre-style, radium, react-css-builder, react-css-components, react-css-modules, react-cssom, react-fela, react-free-style, react-inline-css, react-inline-style, react-inline, react-jss, react-look, react-native-web, react-statics-styles, react-styl, react-style, react-styleable, react-stylematic, react-theme, react-vstyle, reactcss, restyles, scope-styles, smart-css, stile-react-media-queries, stilr, stylable, style-it, styled-components, styled-jsx, styletron-react, styling, superstyle, typestyle, uranium
Such a fragmented ecosystem was far from appealing. Which one should you pick, (if any)?
GitHub stars are one useful metric:
However, GitHub stars say nothing about a project’s trajectory — perhaps they were accumulated long ago and the repo has since fallen out of favor or is no longer maintained. Glamor has plenty of open issues, and hasn’t seen a commit in over a year. Its author advises:
…it mostly works, I’m not going to do any major changes… if you need something more modern, I’d recommend emotion, it mostly matches glamor’s api, and is actively maintained.
The similarly named Glamorous was recently deprecated with its author also recommending users switch to Emotion:
At the time, Emotion had some features that Styled Components didn’t. Since then, Styled Components has made some big announcements.
styled-components v3.3.0 is out with first-class object support! 😍
Lots of people have been asking for this, your wishes have been heard! Shoutout to @probablyup for taking care of this release.
👉 https://t.co/yOHWg78nF4 pic.twitter.com/Ic8fZdAFVs
— Max Stoiber (@mxstbr) May 25, 2018
Emotion also offers a
css prop, which Styled Components didn’t have, until…
🎉 Announcing support for the
cssprop in styled-components! 🎉
This has been a long time coming, hope y'all enjoy! ✨
Huge shoutout to @satya164 for coming up with the ingenious implementation! 👏
— Max Stoiber (@mxstbr) November 26, 2018
The rival CSS-in-JS libraries have stolen from each other until landing upon the same feature set and the same syntax — Emotion and Styled Components have an almost identical API. What once felt like a total mess of competing methodologies and libraries now feels somewhat stable. Even if CSS-in-JS hasn’t standardized on a dependency, it now has standardized a way of doing things — they’re just implemented differently:
Internally, quite a bit. SC has a lot of complexity around organizing style tag order.
Re css prop: SC requires Babel plugin and uses the entire SC custom component creation. Emotion will skip the custom component if it can and just renders the element with the className directly
— Kye Hohenberger (@tkh44) December 7, 2018
Styled Components is by far the most popular CSS-in-JS library, but Emotion has seen a rapid increase in usage.
Both are used by some major companies. Styled Components are utilized by plenty of large companies, including Bloomberg, Atlassian, Reddit, Target, BBC News, The Huffington Post, Coinbase, Patreon, Vogue, Ticketmaster, Lego, InVision and Autodesk just to name a few.
Emotion boasts fewer recognizable names, but has been recently adopted by the New York Times.
Great article about the launch of our new Story designs on the NYT today. It mentions our Shared Components initiative – would have been impossible without Emotion / CSS-in-JS. Absolute game-changer. Living in the future. https://t.co/pZLDJjsbEr
— Scott Taylor (@wonderboymusic) May 8, 2018
While these libraries certainly do seem to be most popular amongst React users, they can be used with other frameworks. While they seem to have converged on the same features at last, it’s difficult to say whether this is the end point of CSS-in-JS, or whether we’ll see a continued evolution from here.
I mainly use Vue.js. Am I right in thinking that CSS-in-JS is more of a React thing because it does not have single file components where you can add CSS? I’m not sure what problem CSS-in-JS solves.
If you’re using
<style scoped>in your Vue files, then yep, you’re using CSS-in-JS (with style scoping) and you don’t really need to worry about the landscape of tooling around this idea.
The problem it’s solving is the fact that CSS is global. It prevents styles leaking from one componentent to another (and also gives some other advantages, like dynamic styles and maybe some other stuff).
React has single file components (for instance styled-jsx or react-csjs) but very few people use it. In React a styled-component is a real component, styles aren’t ripped from scope, they can receive props and create dynamic output.
JSS works nicely with Angular, here’s a guide on how to do it:
I like styled components, but Emotion is closer to my heart. Both are great really. I would not trade back to using “normal” css or Sass for anything in this world. Working with css-in-js and React is such a beautiful match!
Maybe you could add the most popular CSS-in-JSS package (@emotion/core – for React users) to the npmtrends graph? I think it gives a better picture of the current situation.