CSS Modules vs Styled Components

View other answers to this thread
Start a personal dev blog on your domain for free and grow your readership.

3.4K+ developers have started their personal blogs on Hashnode in the last one month.

Write in Markdown · Publish articles on custom domain · Gain readership on day zero · Automatic GitHub backup and more

Lorefnon's photo

CSS modules are an evolution over vanilla css in that they solve the problem of scoping for you.

Styled components library does that, but also enforces that styles are applied through Higher order components, which is a good practice. In addition it provides good support for theming etc.

So if you prefer stronger conventions, styled-components is a better option. However getting editor support for highlighting css in tagged template literals may be tricky in some editors (I have spent better part of a day trying to make code look pretty in emacs web-mode), even though support is available for many popular ones.

CSS modules may be easier to adopt if your team has dedicated web designers who write CSS and are not much familiar with JS and javascript is managed by a separate team. In a workflow where static HTML+CSS mocks are provided by designers and they are integrated by separate UI developers, css-modules may work better, and will allow designers to continue using their existing tooling and file organization etc.

Also, if you plan on using SCSS/stylus etc. for generating the css, css-modules are your only option at the moment, though that may change in future.

Also, with styled-components wrapping third party components can require additional boilerplate, because styled-components builds upon the assumption that components accept className prop and apply it to the top level node.

If that is not the case, then things will fail silently. With CSS modules, it is easier accomodate rogue components that do not follow this convention. At best, the component will accept some other prop, through which class names can be passed, at worst, in componentDidMount/componentDidUpdate hooks you can inject the relevant class into the DOM directly. This is most certainly not a good practice, but somethings forking a component for some small UI change becomes a frustrating endeavour.