Linaria Logo

Linaria: Zero-Runtime CSS-in-JS

Fast and Efficient. Discover how Linaria extracts styles at build time, shrinking your bundle size and speeding up your website.

typescript
    
      import { styled } from '@linaria/react';

const Button = styled.button`
  background-color: rebeccapurple;
  color: white;
  padding: 10px 15px;
  border: none;
  border-radius: 4px;

  &:hover {
    background-color: darkmagenta;
  }
`;

// Usage: <Button>Click Me</Button>
    
  

What is Linaria and Why This Site?

Linaria is a modern CSS-in-JS library with a unique superpower: zero runtime. Unlike many other popular solutions that parse and inject styles when your JavaScript runs in the browser, Linaria does all the heavy lifting during the build process. This solves a common performance bottleneck associated with traditional CSS-in-JS – the runtime overhead that can slow down rendering and increase your JavaScript bundle size.

This page serves as a focused deep dive into Linaria. We'll explore its core concepts, highlight its key advantages, compare it directly with other styling approaches, and provide a quick guide to get you started.

Here's what you'll find:

  • An explanation of the crucial Zero-Runtime concept.
  • A breakdown of Linaria's features and benefits.
  • A comparison with popular alternatives like Styled Components and Emotion.
  • A practical quick-start guide.

The Core Concept: Zero-Runtime CSS-in-JS

The fundamental principle behind Linaria is its build-time style extraction. When you write styles using Linaria's css or styled template tags within your JavaScript or TypeScript files, Linaria's tooling (integrating with bundlers like Webpack or Rollup via Babel presets/plugins) processes these tags during your application's build step.

Instead of shipping JavaScript code that needs to interpret these style tags in the user's browser, Linaria evaluates them at build time. It generates actual CSS rules and extracts them into separate .css files. The original Linaria-specific code is then removed from your JavaScript bundle, leaving only the necessary class names or component logic. This means there's no Linaria library code executing in the browser just to handle styles – hence, "zero runtime".

JS Code with Linaria
import { styled } from "@linaria/react";

const Button = styled.button`
background: ${colors.primary};
color: white;
`;
Build Process
(Webpack/Rollup + Linaria Plugin)
Separate CSS File
.button_a1b2c3 {
background: #DE2D68;
color: white;
}
Cleaned JS File

Here's a basic idea of how you might write styles:

typescript
    
      import { styled } from '@linaria/react';

const Button = styled.button`
  background-color: rebeccapurple;
  color: white;
  padding: 10px 15px;
  border: none;
  border-radius: 4px;

  &:hover {
    background-color: darkmagenta;
  }
`;

// Usage: <Button>Click Me</Button>
    
  

Key Features and Benefits

Linaria's zero-runtime approach unlocks several significant advantages for web development:

Zero Runtime Overhead

As styles are extracted to static CSS files, there's no runtime library needed to process styles in the browser.

Reduced JS Bundle Size

Removing style definitions and the styling library's runtime from your JavaScript significantly shrinks its size.

Parallel CSS & JS Loading

Since CSS is in separate files, browsers can download and parse CSS in parallel with JavaScript.

Familiar CSS Syntax

Write standard CSS (including nesting, pseudo-selectors, media queries) within your JavaScript/TypeScript files.

Dynamic Styles via CSS Variables

Handle dynamic styling based on props efficiently using CSS Custom Properties, which are native to the browser.

CSS Source Maps

Debugging is straightforward as Linaria generates source maps, allowing you to inspect elements.

Linter Integration

Use tools like Stylelint to lint your CSS code written within the template tags, ensuring code quality.

JavaScript for Logic

Leverage the power of JavaScript for complex logic when defining your styles.

Linaria vs. Alternatives: A Focused Comparison

Choosing a styling approach involves trade-offs. Linaria stands out due to its build-time nature. Here's how it compares to other popular CSS-in-JS libraries and CSS Modules:

Feature/AspectLinariaStyled ComponentsEmotion (@emotion/styled)CSS Modules
Runtime OverheadNoneYesYesNone
JS Bundle ImpactMinimal (class names only)Adds Runtime LibraryAdds Runtime LibraryMinimal (class names)
Dynamic StylesCSS VariablesJS-driven (runtime)JS-driven (runtime)Via JS manipulation
Style ProcessingBuild TimeRuntimeRuntimeBuild Time
SSR SupportOut-of-the-boxRequires setupRequires setupN/A (handled by build)
Atomic CSS SupportYes (`@linaria/atomic`)Possible via patternsPossible via patternsPossible via patterns
SyntaxCSS-in-JS (Tagged Templates)CSS-in-JS (Tagged Templates)CSS-in-JS (Tagged Templates)Separate `.css` files

Quick Start / Basic Usage

Getting started with Linaria involves installing the necessary packages and configuring your build tool (like Webpack, Rollup, Vite, etc.) to use the Linaria plugin/preset.

Installation:

Install the core library, the framework integration (e.g., for React), and the Babel preset:

npm install --save-dev @linaria/core @linaria/react @linaria/babel-preset
# or
yarn add --dev @linaria/core @linaria/react @linaria/babel-preset

Build Configuration:

Add Linaria's Babel preset to your Babel configuration:

{
  "presets": ["@linaria"]
}

Frequently Asked Questions

Answers to common questions about using Linaria in your projects

Is Linaria suitable for large-scale applications?
Absolutely! Linaria is particularly well-suited for large applications where performance is critical. The zero-runtime approach helps maintain fast load times even as your application grows, and the static CSS extraction makes scaling more predictable.
How does Linaria handle dynamic styles?
Linaria uses CSS variables (custom properties) for dynamic styling. During build time, Linaria extracts static CSS and replaces dynamic values with CSS variables that can be updated at runtime through JavaScript without requiring style recalculation or re-injection.
Can I use Linaria with Next.js or other frameworks?
Yes, Linaria integrates well with Next.js, React, Vue, Svelte and other frameworks. There are official integrations for most popular frameworks and build tools including webpack, rollup, and vite.
How does debugging work with Linaria?
Linaria generates source maps, which allow you to trace styles back to your original JavaScript files in browser dev tools. This makes debugging as straightforward as with traditional CSS files.
Does Linaria support server-side rendering?
Yes, Linaria works excellently with SSR since the styles are extracted at build time. This eliminates common SSR issues with CSS-in-JS libraries that require runtime style injection.

Conclusion: When Should You Choose Linaria?

Linaria shines in scenarios where performance and minimal JavaScript footprint are critical priorities, without sacrificing the developer experience benefits of writing styles alongside your components.

Consider Linaria if:

  • You are building performance-sensitive applications.
  • Reducing JavaScript bundle size is a key goal.
  • You prefer writing CSS within your JavaScript/TypeScript files.
  • You are building static sites or sites where initial load time is crucial.
  • You are creating reusable components or design systems where runtime style calculation is unnecessary overhead.

While runtime CSS-in-JS libraries offer more flexibility for complex dynamic styles directly driven by JavaScript logic at runtime, Linaria provides an excellent balance of developer experience and end-user performance by leveraging build-time extraction and CSS Custom Properties.