REGISTER

Zero-runtime CSS from JS with Linaria

Satyajit Sahoo
2017-09-05

blog content

Need help with React Native?
hire us
Our React Native EU Conference is back
register nowlearn more

Linaria is a library which allows you to write CSS inside your JavaScript without the runtime cost. The CSS is extracted out to plain old CSS files with the Babel preset, and critical CSS can be determined with the included helpers.

The idea for Linaria came from css-literal-loader and the syntax of styled-components. It also uses the same parser as styled-componentsGlam by Sunil Pai has been another great source of inspiration.

The API looks like this:

You write CSS syntax (plus nesting) in a tagged template literal and tag it with the css function from Linaria. It returns a class name for you to use. This gets optimized with the Babel preset which reduces it down to just a class name:

It’s possible to use JavaScript expressions inside the template literal and they will be evaluated at build time, useful for shared utility functions and constants:

You can also compose multiple styles together with the include helper:


…which is equivalent to writing:

Features

  • CSS is extracted at build time, no runtime is included
  • JavaScript expressions such as function calls, variables, conditionals etc. are supported and evaluated at build time
  • CSS can be extracted for inlining during SSR
  • CSS syntax with Sass like nesting
  • Integrates with existing tools like Webpack to provide features such as Hot Reload

Why?

Existing CSS in JS libraries are pretty amazing as they provide several benefits over the traditional way of writing CSS, making it much more maintainable. They also come with its costs:

  • CSS needs to be parsed, auto-prefixed and applied to the document at runtime
  • Bundle-size is increased as the CSS parser needs to be bundled with JavaScript bundle
  • CSS code is bundled with JavaScript, making it impossible to download and parse both in parallel
  • Even if you do SSR and serve CSS in parallel, the same CSS is still duplicated in the JavaScript bundled, and wastefully parsed again

These costs may not be significant for all applications, and most of the time, it outweighs the benefits gained from CSS in JS.

The main goal of Linaria is to provide a similar level of flexibility and maintainability while not having the runtime cost associated with it.

What’s the difference from CSS modules?

It’s pretty similar, except a few key differences:

  • You can write CSS in the same file as rest of the component, no back n forth between files
  • You can share configuration between your CSS and JavaScript without having to keep multiple files in sync
  • You can just use JavaScript for loops, conditionals etc., along with various JavaScript libraries like polished
  • You can make sure that you don’t have any CSS you don’t use with linters like ESLint, and it also works with tools likes Flow or Jest

What’s the difference from other CSS in JS libraries

Despite the similarities, there are many differences from the existing CSS in JS libraries:

  • The CSS is extracted out from the JavaScript completely, and no runtime is left
  • It is required that all the CSS can be evaluated at build time, which means it’s currently not possible to use dynamic values like props
  • The CSS can be served as a separate file, improving load time by parallelizing the downloads and decreasing parsing time

If you are wondering what’s the difference from Emotion, see here.

Want to give it a try? Check it out at https://github.com/callstack-io/linaria/. Don’t forget to star it!

We’re still actively working on it, so please report any issues you find. Pull requests are always welcome.

Author:
Satyajit Sahoo
Satya is in the 2016 Facebook’s TOP 5 external contributors list. You can find him everywhere. Satya is also a React & React Native ninja that will make your apps to stand above the others.
arrow icon
MORE posts from this author

learn more

More posts from this category

stay tuned

Subscribe to our newsletter

You may unsubscribe from these communications at any time. For details see the Privacy Policy.