The most important factor that differentiates CSS-in-JS libraries is how dynamic they are. By that we
mean whether a CSS-in-JS library can use JavaScript variables in its templates, and — if so —
to what scope of variables those templates have access to? Module scope? Component scope? Or maybe
.render()
method scope?
Below we define five generations of CSS-in-JS libraries based on their template dynamicity and whether they use inline styles or inject actual CSS; starting from generation one — for the most static libraries — and going all the way up to generation five. Although not strictly true, this also corresponds to how React styling libraries evolved over time.
First generation React styling libraries don't allow you to write styling in JavaScript and use any of
JavaScript variables, instead, you have to use CSS pre-processors. The CSS source files are usually
located in separate .*css
files.
- Notable example:
css-modules
Second generation React styling libraries emit inline styles in style
property of your React
elements, but are very dynamic, because they can use even .render()
method scope variables. However,
they use inline styles, thus, you don't get all the benefits of CSS.
- Notable example:
Radium
Third generation React styling libraries allow you to write CSS templates in JavaScript and inject actual CSS into
DOM <style>
tags. However, the templates are static,
in a sense that they are defined in module scope, and thus they can't use component props
. The reason why they are "static" is
because they have access only to module scope JavaScript variables, which evaluate only once when the module is imported for the first time.
Examples: aphrodite
, cssx
, glamor
, typestype
, styletron
Just like 3rd generation libraries, fourth generation React styling libraries also emit CSS into DOM <style>
tags,
but their templates are more dynamic because they have access to component scope variables, such as props
and state
. Fourth generation
templates normally also re-render on every component prop or state change.
Examples: styled-components
, glamorous
Fifth generation React styling libraries are even more dynamic than fourth generation, fifth generation libraries
can use JavaScript variables from component's .render()
function scope.
Examples: freestyler
, style-it
, superstyle
Generation | Emits CSS | Module scope variables | Component scope variables | Render method scope variables |
---|---|---|---|---|
1st Generation | ✅ | ❌ | ❌ | ❌ |
2nd Generation | ❌ | ✅ | ✅ | ✅ |
3rd Generation | ✅ | ✅ | ❌ | ❌ |
4th Generation | ✅ | ✅ | ✅ | ❌ |
5th Generation | ✅ | ✅ | ✅ | ✅ |
Libraries grouped by generation.
- 1st Generation
- 2nd Generation
- 3rd Generation
- 4th Generation
- 5th Generation