Zero-Runtime CSS From JS With Linaria

No items found.

In short

Linaria is a JavaScript library allowing CSS to be written within JavaScript without incurring runtime costs. It extracts CSS to separate files during the build process, addressing issues like runtime overhead and duplicated CSS in JavaScript bundles. With features like support for JavaScript expressions at build time and seamless integration with tools like Webpack, Linaria aims to offer the flexibility and maintainability of CSS-in-JS without the associated runtime drawbacks.

Introduction to Linaria

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.

How does it differ 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

How does it differ from other CSS in JS libraries?

Despite the similarities, there are many differences between Linaria and 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

When it comes to Emotion, there's a separate post on how Linaria differs from Emotion and styled components.

Want to give it a try? Check Linaria on GitHub, and 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.

FAQ

No items found.
React Galaxy City
Get our newsletter

By subscribing to the newsletter, you give us consent to use your email address to deliver curated content. We will process your email address until you unsubscribe or otherwise object to the processing of your personal data for marketing purposes. You can unsubscribe or exercise other privacy rights at any time. For details, visit our Privacy Policy.

Callstack astronaut
Download our ebook

I agree to receive electronic communications By checking any of the boxes, you give us consent to use your email address for our direct marketing purposes, including the latest tech & biz updates. We will process your email address and names (if you have entered them into the above form) until you withdraw your consent to the processing of your names, or unsubscribe, or otherwise object to the processing of your personal data for marketing purposes. You can unsubscribe or exercise other privacy rights at any time. For details, visit our Privacy Policy.

By pressing the “Download” button, you give us consent to use your email address to send you a copy of the Ultimate Guide to React Native Optimization.