Announcing Linaria 1.0

The first major release of Linaria is here. It’s more robust, handles more edge cases and introduces a new API to make easier to use with React.

Linaria is a zero-runtime CSS in JS library. What’s special about Linaria is that it extracts all of the styles you write in your JavaScript code to real CSS files, unlike other CSS in JS libraries which parse and apply the styles in the browser. From one of our posts, you can find out how it is different from Emotion and Styled Components.

For a list of features and benefits over other solutions, check our GitHub repo.

Highlights

Rewritten core to be more robust

We have changed the approach of how we evaluate and extract styles. This fixed some long-standing issues and made it easier for us to support features like sourcemaps, improved stylelint preprocessor, the new <rte-code>styled<rte-code> tag for components, etc.

Support for Babel 7

The Babel plugin is now written with the latest stable version of Babel, so you don’t have to stay on an older version of Babel anymore. It also brings TypeScript support!

We also support Babel’s caller option to make it easier to provide a different configuration for Linaria’s evaluation.

Support for CSS sourcemaps

It was always tricky to find the file where you wrote the styles. Now it’s much easier thanks to sourcemaps support. You can jump to the original JavaScript file from the line where the CSS was generated from the dev tools.

screenshot presenting linaria support for css sourcemaps

It’s recommended to enable sourcemaps during development. The sourcemaps are inlined into the CSS files, so don’t enable them in production.

New <rte-code>styled<rte-code> tag for React components

Since the first release of Linaria last year, we’ve been looking for new ways to improve the way we write our styles. One feedback we got was that people missed being able to dynamically apply styles based on a React component’s props. Many also preferred the abstraction styled-components provided as opposed to using class names.

Now, we have added a new <rte-code>styled<rte-code> tag à la styled-components. It makes it super easy to create a React component with some styles:

import { styled } from 'linaria/react';
const Button = styled.button`
appearance: none;
background-color: ${colors.primary};
border: 2px solid ${colors.primary};
color: white;
&:hover {
background-color: transparent;
color: ${colors.primary};
}
`;
view raw gistfile1.txt hosted with ❤ by GitHub

In addition to that, the <rte-code>styled<rte-code> tag also supports dynamic prop based styling leveraging CSS custom properties (aka CSS variables). You can write a function interpolation and we automatically convert it to a CSS variable:

import { styled } from 'linaria/react';
const Box = styled.div`
height: ${props => props.size}px;
width: ${props => props.size}px;
background-color: ${props => props.color};
border: 2px solid white;
margin: 16px;
`;
<Box size={48} color='blue' />
view raw gistfile1.txt hosted with ❤ by GitHub

The variables are scoped to the class name.

We optimize how many CSS variables we generate automatically, so you can write idiomatic code. For example, in the above code, even though there are 3 dynamic interpolations, we’ll only generate 2 CSS variables because 2 of the dynamic interpolations have the same expression.

CSS variables code screenshot

We also transparently handle some edge cases like having interpolations followed by units. For example, the following code won’t work in vanilla CSS:

height: var(<strong>--box-height</strong>)px;
view raw gistfile1.txt hosted with ❤ by GitHub

The <rte-code>px<rte-code> unit needs to be part of the CSS variable or should be applied with <rte-code>calc<rte-code>, e.g. — <rte-code>calc(var(--box-height) * 1px)<rte-code>. But you don’t have to worry about doing that manually when writing interpolations. We detect interpolations followed by units and apply them correctly.

A limitation of using CSS variables for dynamic values is that they only work for property values, and you can’t place them arbitrarily like you can with <rte-code>styled-components<rte-code>. For example, the following code won’t be valid:

@media(min-width: ${props => props.minWidth}) {
font-size: 16px;
}
view raw gistfile1.txt hosted with ❤ by GitHub

New CLI for libraries

The Babel plugin no longer writes the CSS files to the filesystem due to several issues with the approach, which means you can’t use Babel CLI to extract the CSS to files anymore like in the previous versions. So we added a new CLI to do just that.

screenshot presenting new cli for libraries in linaria

For example, to extract CSS files from the JS files inside <rte-code>src<rte-code> to <rte-code>dist/styles<rte-code>, you can run the following command:

npx linaria --out-dir dist/styles src/**/*.js
view raw gistfile1.txt hosted with ❤ by GitHub

There are also other features such as inserting require statements to built JS files for publishing libraries. Check the GitHub docs for the full list of features.

New Rollup plugin

Thanks to external contributor John Holmerin, we now have a plugin for Rollup.

Improved stylelint processor

The stylelint processor can now correctly report errors inside interpolations.

screenshot presenting improved styleint processor in linaria

Due to our build time evaluation, it can provide much better error messages as if you’re linting plain CSS files.

Support for using preprocessors

By default, Linaria uses stylis to process the extracted CSS. You can now disable or override this behavior which lets you use any CSS preprocessor you like, such as Sass, Less or custom PostCSS syntaxes.

Many bugfixes and enhancements

We fixed several issues and added many nice improvements. Some of them are:

  • Support a config file to configure Linaria: <rte-code>linaria.config.js<rte-code>
  • Ship typescript declarations in the npm package.
  • Play nice when you’re using Linaria in the same codebase where you use other CSS in JS libraries with the same syntax. The Babel plugin will check if you’re importing <rte-code>css<rte-code> and <rte-code>styled<rte-code> from Linaria before processing the file.
  • Support using <rte-code>styled<rte-code> helper with Preact (with webpack alias).
  • Support webpack aliases when evaluating modules.
  • Fix issues with resolving <rte-code>url(..)<rte-code> expressions when using <rte-code>file-loader<rte-code> and <rte-code>url-loader<rte-code>.
  • Fix cases where output CSS had missing class names.
  • Fix issues with path on windows.
  • Fail for invalid interpolations such <rte-code>null<rte-code>, <rte-code>NaN<rte-code> etc. at build time to avoid mistakes.
  • Many more.

Summary

Linaria, the CSS in JS library, just dropped its major release. The core has been rewritten, offering better support for features like sourcemaps, stylelint preprocessor, and a new styled tag for components. The release includes support for Babel 7, CSS sourcemaps, a new styled tag for React components, a CLI for libraries, and a Rollup plugin. It also improves the stylelint processor, supports preprocessors like Sass and Less, and introduces numerous bug fixes and enhancements. Check out Linaria's GitHub repo for details and updates.

Insights

Learn more about Open Source

cover

Aug 7Article

Visualizing Open Source Licenses to Analyze Compliance and Reduce Legal Risk

Discover how license-kit visualize maps and analyzes your dependency graph, helping you spot license issues, duplicates, and restrictive packages with interactive views, stats, and AI-powered summaries.

cover

Mar 26Podcast

How Definitely Typed Changed TypeScript Forever

Discover the story behind Definitely Typed with its creator, Boris Yankov, and learn how it became essential for type-safe JavaScript in the TypeScript ecosystem.

cover

Oct 14Article

Introducing the OMH Cloud Storage Module

Discover the OMH Cloud Storage Module. This open-source solution simplifies cloud storage integration for React Native apps.

cover

Jul 12Article

Introduction to the React Native OMH Maps Library

Discover how the React Native OMH Maps library simplifies map integration with cross-platform compatibility, ease of use, and customization options.

cover

Apr 22Podcast

Behind the Scenes of React Native 0.74 Release

Join the release crew members to find out what new features and improvements React Native 0.74 brings to the cross-platform development world.

cover

Apr 27Podcast

Callstack OSS Update

April 2023 Callstack OSS Update: RFC for Expo Config Plugins, Re.Pack & Paper news.

cover

Dec 6Article

React Native Paper 5.0 - What’s New?

React Native Paper 5.0 is here! Dive into the latest updates and improvements.

cover

Feb 8Article

Stripe React Native: the Most Common Questions - Tipsi Migration Guide, Part 5

Check out the list of the most common questions about Stripe react Native Library prepared by Jakub Kłobus, software engineer at Callstack.

cover

Feb 6Article

Stripe React Native Migration Function by Function - Tipsi Migration Guide, Part 3

In the third part of the Tipsi Migration Guide we describe the Stripe React Native migration function by function.

cover

Mar 19Tutorial

The Hard Way vs. The React Native AI SDK Way: Stop Writing Custom Modules for Every Model

Learn how React Native AI uses a unified provider model to switch between cloud and on-device LLMs without rewriting application logic, enabling reliable AI experiences online and offline.

cover

Mar 12Tutorial

Build Smarter Apps: Tool Calling & AI Orchestration Explained

Learn how on-device models in React Native can call tools, interact with external APIs, and return structured outputs you can use directly in application logic.

cover

Mar 5Tutorial

MLC LLM + React Native: On-Device AI Without the Pain

Learn how to run third-party on-device LLMs in React Native using MLC LLM. Choose your models, run them efficiently across platforms, and keep a unified JavaScript API with React Native AI.

cover

Feb 24Tutorial

Intelligent Fallbacks with Apple Intelligence in React Native

Learn how to use Apple’s built-in Foundation Models in React Native apps, reduce memory usage, and enable fast, fully on-device AI with React Native AI Apple.

cover

Feb 10Tutorial

What Is the React Native AI SDK? A Complete Intro & Quickstart

Learn why on-device AI matters for React Native apps, how local LLMs behave offline, and what problems React Native AI is designed to solve from day one.

cover

Jan 29Tutorial

Implementing an Android TurboModule with Kotlin

Learn how to implement a React Native TurboModule on Android, from the TypeScript spec and Codegen to the Kotlin implementation and package registration.

cover

Jan 19Tutorial

Working with Different Threads in Swift TurboModules

Learn how JavaScript, native module, background, and main threads interact in React Native TurboModules, and how to use GCD queues to run async work safely in Swift.

cover

Jan 9Tutorial

How to Add Type-Safe Constants to Swift TurboModules

Learn how to expose typed, immutable constants from a Swift TurboModule using Codegen, and get full end-to-end type safety between native and JavaScript.

cover

Dec 30Tutorial

Adding Event Emitters to Your TurboModule in Swift

Learn how to emit native events from a Swift TurboModule and subscribe to them in JavaScript, including proper memory management and Codegen integration.

cover

Dec 22Tutorial

Writing Your First TurboModule in Swift

Learn how to build a fully working TurboModule in Swift, integrate it with Codegen, and bridge it through Objective‑C inside an Expo app.