Why Did I Quit Styled-Components for Linaria?

October 19, 20214 min read

In brief, CSS in JS libraries like Emotion and Styled Components parse and apply your styles when your page loads in the browser, whereas Linaria extracts the styles to CSS files when you create your project (e.g. with webpack), and the CSS files are loaded regularly.


On the Linaria website they say; Write CSS in JS and get real CSS files during the build. Use dynamic prop-based styles with the React bindings and have them transpire to CSS variables automatically. Great productivity with source maps and linting support.

Linaria Features:

  • Write CSS in JS, but with zero runtime, CSS is extracted to CSS files during the build
  • Familiar CSS syntax with Sass like nesting
  • Use dynamic prop based styles with the React bindings, use CSS variables behind the scenes
  • Easily find where the style was defined with CSS source maps
  • Lint your CSS in JS with stylelint
  • Use JavaScript for logic, no CSS preprocessor is needed
  • Optionally use any CSS preprocessor such as Sass or PostCSS

Advantages Over Styled-Components Solutions

1. CSS is downloaded and parsed separately from JS

Since the styles are extracted to separate CSS files, the CSS and JavaScript can be downloaded and parsed by the browser in parallel and can improve the load time.

2. No extra parsing needed for CSS

Many CSS-in-JS libraries use a custom parser on the client to parse the CSS string. The introduction of the parser increases the bundle size (although marginally). Furthermore, until the JavaScript code is parsed and run, the CSS cannot be processed, which might be noticeable, especially on low-end devices and larger JS bundles.

Linaria is unusual in that it does not require a runtime to function. Styles are processed, assessed, and produced at build time, so no additional processing on the client is required.

3. No style duplication on SSR

When using component-based CSS in JS libraries, displaying the same component with various props might result in numerous instances of the same set of styles. It has no effect on the client, however, it may increase the size of the rendered CSS when using SSR. It may not be seen in most situations, but when rendering a long list of components with minor changes in style, it can soon mount up.

Furthermore, when you use SSR, the rendered CSS is downloaded in addition to the CSS you wrote in JS files, which increases the size even more.

Linaria generates only one rule set per declaration, and differences are handled with CSS variables, so there is no repetition, which is fantastic for lowering bundle size.

Since Linaria works at build time, you don’t need to have SSR set up to improve the time to first paint or for your page to work without JS.

4. Familiar CSS syntax

Linaria, unlike some CSS in JS libraries, allows you to use regular CSS syntax, which means you can copy and paste styles from the browser's dev tools (or StackOverflow) while avoiding needless noise in the styles.

If you want, you may use a preprocessor like Sass.

5. Works without JavaScript

Linaria is an excellent choice for styling websites that do not require JavaScript or that produce HTML in advance at build time.

6. Automatic unused styles removal

Linaria removes unneeded styles from a file unless it is exported. Linters such as ESLint may also alert you about unused styles because they are just JS variables.

My Personal Thoughts for Linaria

One of the solutions to improving lost performance time due to double parsing is that the libraries should convert the CSS-in-JS block into a separate .css file first. Then, the browser will read and apply those styles to the webpage, ultimately saving runtime that’s typically wasted while generating a style tag. This is called zero-runtime CSS-in-JS. It is particularly useful for scaled or complex projects where performance is key.

If you care about static or prerendered webpages (for example, Gatsby), Linaria may be a better alternative for your static output.