DEV Community

Cover image for CSS Modules vs CSS-in-JS. Who wins?

CSS Modules vs CSS-in-JS. Who wins?

Sergey on March 11, 2021

Introduction In modern React application development, there are many approaches to organizing application styles. One of the popular way...
Collapse
 
dastasoft profile image
dastasoft

One pro of CSS, the hot reload is instant when you just change CSS, with CSS in JS the project is recompiled. For CSS-in-JS I find easier to reuse that code in a React Native project.

My personal conclusion is that we are constantly trying to avoid CSS but at the end of the day, CSS will stay here forever.

Great article btw!

Collapse
 
greggcbs profile image
GreggHume • Edited

I ran into issues with css modules that styled components seemed to solve. But i ran into issues with styled components that I wouldn't have had with plain scss.

So some things to think about:
Styled components is a lot more overhead because all the styled components need to be complied into stylesheets and mounted to the head by javascript which is a blocking language.

On SSR styled components get compiled into a ServerStyleSheet that then hydrate the react dom tree in the browser via the context api. So even then the mounting of styles only happens in the browser but the parsing of styles happens on the server - that is still a performance penalty and will slow down the page load.

In some cases I had no issues with styled components but as my site grew and in complex cases I couldn't help but feel like it was slower, or didn't load as smoothly... and in a world where every second matters, this was a problem for me.

Here is an article doing benchmarks on CSS vs CSS in JS:
pustelto.com/blog/css-vs-css-in-js...

I use nextjs, it is a pity they do not support component level css and we are forced to use css modules or styled components... where as with Nuxt component level scss is part of the package and you have the option on how you want the sites css to bundled - all in one file, split into their own files and some other nifty options. I hope nextjs sharped up on this.

Collapse
 
kachidk profile image
Nwanguma Victor • Edited

A big tip that might help.
Why not use SCSS and unique classNames: For example create a unique container className (name of the component) and nest all the other classNames under that unique container className.

.home-page-guest {
  .nav {}
  .main {}
  .footer {}
}
Enter fullscreen mode Exit fullscreen mode
<div className="home-page-guest">
  <div className="nav" />
  <div className="main" />
  <div className="footer" />
</div>
Enter fullscreen mode Exit fullscreen mode
Collapse
 
fantasticmrhank profile image
Hank Queston

I agreed, CSS Modules make a lot more sense to me over Styled Components, always have!

Collapse
 
Sloan, the sloth mascot
Comment deleted
Collapse
 
alienpr84 profile image
Alien Padilla Rodriguez

@Petar Kokev If something I learned from this years of working with React and other projects is that the correct library for project isn't the correct library for another. So the mos important think that we need to do is select the tools, libraries and technologies that fit better to the current project. In this case you can't use Styled-components on sites that require a good SEO, becouse the mos important think here is the SEO and you cant sacrify it.

Collapse
 
thekooldev1232 profile image
thedev1232

How about having to deal with libraries like Material UI with next js?

I have an issue to decide whether to use just makeStyles function or should we use styled components?

My main concern is code longevity and maintenance without any issues

Collapse
 
goldhand profile image
Will Farley

My big issues with styled components is they are deeply coupled with your code. I've opted to use emotion's css utility exclusively and instructed my team to avoid using any of the styled component features. We've loved it but this was a few years ago. For newer projects I'm going with the css modules design.
Also why does anyone care about sass anymore? With css variables and the css nesting module in the specification, you get the best parts of sass with vanilla css. The other features are just overkill for a css-module that should represent a single react component and thus nothing :global. Complicated sass directives and stuff are just overkill. Turn it into a react component and don't make any crazy css systems.

Collapse
 
kachidk profile image
Nwanguma Victor

Same I was trying to revamp my personal site, I discovered that I would have to rewrite alot of things, and then I later gave up. I would advice css modules are the way to go, and it greatly helps with SEO.
And in teams using SC, naming becomes an issue because some people don't know how to name components and you have to scroll around, just to check if a component is a h1 tag 🤮
CACHEing I can't stress this enough, for enterprise in-house apps it doesn't really matter, but for everyday consumer-essentric apps CACHEing should not be overlooked

Collapse
 
goldhand profile image
Will Farley

You can still have a top-level css file that isn't a css module for global stuff

Collapse
 
kibobishtrudelz profile image
Petar Kolev

It is not true that with styled-components one can't use scss syntax, etc. styled-components supports it.

Collapse
 
edshav profile image
Eduard

How about css-in-js frameworks like material-ua, chakra-ui and others? In my opinion, they dramatically speed up development.

Collapse
 
gass profile image
Gass • Edited

Good post. I've been using CSS modules for a short time now and I like it. Allows everything to be nicely compartmentalized.

I also like that it gives more freedom to name classes in smaller chunks of CSS code.

Instead of using it like so: {styles.my_class} I preffer {s.my_class} makes the code looks nicer and more concise.

Collapse
 
alienpr84 profile image
Alien Padilla Rodriguez

In my personal opinion I see Styled Components more for a Single Page Aplications where the SEO isn't important and is unecessary to cache css files. In the case of static web site or a site that must have a good SEO the Module-Css is better.

@greggcbs My recomendation is to use code splitting if you have problem with the performans when you use Styled-Components in your project, in order to avoid brign all code in the first load of the site.

Good article @sergey

Collapse
 
drbeehre profile image
DrBeehre

This is awesome!
I'm quite new to Web dev in particular and when starting a new project, I've often wondered which approach is better as I could see pros and cons to both, but I never found the time to dig in.

Thanks for pulling all this together into a concise blog post!

Collapse
 
doctorrokter profile image
Mikhail Chachkouski

Google Lighthouse is saddened by your CSS-in-JS 😀
Whilst such css-in-js frameworks like MaterialUI dramatically speed up development (that's true) they, from another side, beat the app perfomance because of too heavy. In that case CSS modules are more preferred.

Collapse
 
mario_iliev_086178c17d1cd profile image
Mario Iliev

I'm sorry but it seems that you don't have much experience with Styled Components.
"And the last fundamental flaw is the inability to use ready-made approaches and utilities, such as SCSS, Less and Stylelint, and so on."
Not a single thing here is true. SCSS is the original syntax of the package, you can use Stylelint as well. There are a lot more "pros" which are not listed here.
By working with JS you are opened to another world.
I'll list some more "pros" from the top of my head:

  • consume and validate your theme colors as pure JS object
  • consume state/props and create dynamic CSS out of it
  • you have plugins which can be a live savers in cases like RTL (right to left orientation). Whoever had to support an app/website with RTL will be magically saved by this plugin.
  • You can create custom plugins to fix various problems, or make your own linting in your team project.
  • you don't think about CSS class names and collision. I prefer to be focused on thinking about variable names in my JS only and not spending effort in the CSS as well
  • when you break your visual habits you will realise that's it's easier to have your CSS in your JS file just the way you got used to have your HTML in your JS file (React)

In these days CSS has become a monster. You have inheritance, mixins, variables, IF statements, loops etc. Sure they can be useful somewhere but I'm pretty sure that most of you just need to center that div. So in my personal opinion we should strive to keep CSS as simpler as possible (as with everything actually) and I think that Styled Components are kind of pushing you to do exactly that. Don't re-use CSS, re-use components! The only global things you should have are probably just the color theme and animations.

Collapse
 
alessiochiffi profile image
alessiochiffi

With Vue, all you need to do is add scoped to the style attribute

<style lang="scss" scoped>
.myClass {
  background-color: red;
}
</style>
Enter fullscreen mode Exit fullscreen mode
Collapse
 
joetidee profile image
Joe

If you're creating design system within your app, you can cache the js files by splitting your JS bundles.

Collapse
 
schleidens profile image
Schleidens.dev

🚀🚀

Collapse
 
andrewbaisden profile image
Andrew Baisden

Both have pros and cons I alternate between the two.

Collapse
 
altim profile image
Aleksandar Timic

Styled components greatly slow down the project (loading and rendering). In average around 50%. So, if you are working on a complex project I would greatly advise you to use css modules.

Collapse
 
philipvengie profile image
PhilipVengie

My experience is telling me that CSS modules are better withouth any doubts.

Collapse
 
supermod profile image
Stelios Papoutsakis

Hey, nice article, thanks!

While new to the react world, I kind of feel css modules to be more optimal than styled components.