Guide · Open source
How to use vanilla-extract: type-safe styles in TypeScript
Updated · written with AI from the project's own documentation and checked against our catalogue data
vanilla-extract is an open-source library for writing stylesheets in TypeScript or JavaScript. Your styles live in files named .css.ts, and a build step turns them into ordinary static CSS, so none of the styling code ships in your JavaScript. This guide shows you how the pieces fit together so you can write a style, create a theme and use both in your markup.
Quick start
- 1Confirm prerequisites. Make sure Node.js is installed and that your project has a build tool or bundler configured for vanilla-extract, following the documentation site.
- 2Create a .css.ts file. Add a file such as styles.css.ts next to the component that uses it.
- 3Define a theme. Call createTheme with your tokens, such as colour and font, and export the theme class and vars.
- 4Write a style. Call style with properties that reference theme variables, and export the resulting class name.
- 5Import and apply the class. Import the exported class names into your app code and apply them to elements in your markup.
- 6Build and check the output. Run your build so the .css.ts files are evaluated into static CSS, and confirm the styling is applied in the browser.
What vanilla-extract is and who it suits
vanilla-extract lets you write styles in TypeScript (or JavaScript) with locally scoped class names and CSS variables, then generates static CSS files at build time. Its class names are scoped locally, similar to CSS Modules, and it supports themes built on CSS variables.
It suits front-end developers who want type-checked styles, teams using React or another framework, or projects with no framework at all. It is not a fit for people who only write plain CSS, or for projects that need styles computed at runtime from user input.
- Good fit: type-checked styles, build-time CSS output, theme support with CSS variables.
- Poor fit: plain CSS only, no build setup, or styles generated from user input at runtime.
Set up your build tooling
Before you can use vanilla-extract, you need Node.js and a build tool or bundler configured for vanilla-extract. The README points to the documentation site for setup guides for your specific bundler, so follow that guide for your project.
The README also shows how to get a copy of the source repository with git. This is the repository, not an install step for your app. Once your build tooling is configured, the .css.ts files are evaluated at build time.
- Prerequisites: Node.js and a configured build tool or bundler.
- Setup instructions and examples live on the documentation site at vanilla-extract.style.
git clone https://github.com/vanilla-extract-css/vanilla-extractWrite styles in a .css.ts file
Put your styles in a file whose name ends in .css.ts. Import style and createTheme from @vanilla-extract/css. createTheme returns a theme class name and a set of variables you can reference inside style rules, so colours and fonts are defined once.
Each style call returns a class name you can apply to markup. Values such as backgroundColor, fontFamily, color and padding are written as typed object properties rather than as text in a stylesheet.
- Name the file with the .css.ts suffix, for example styles.css.ts.
- Use createTheme to define tokens like color and font.
- Use style to create a class, and reference theme variables such as vars.color.brand.
// styles.css.ts
import { createTheme, style } from '@vanilla-extract/css';
export const [themeClass, vars] = createTheme({
color: {
brand: 'blue'
},
font: {
body: 'arial'
}
});
export const exampleStyle = style({
backgroundColor: vars.color.brand,
fontFamily: vars.font.body,
color: 'white',
padding: 10
});Use the styles in your markup
Import the exported class names into your application code and apply them to elements. The example below wraps a heading in a section that carries the theme class, and gives the heading the style class.
Because the styles are compiled at build time, you use the exported names directly. The README's example writes the markup with document.write, but the same class names can be applied in any framework that accepts class names.
// app.ts
import { themeClass, exampleStyle } from './styles.css.ts';
document.write(`
<section class="${themeClass}">
<h1 class="${exampleStyle}">Hello world!</h1>
</section>
`);Understand what happens at build time
vanilla-extract is a zero-runtime approach. The .css.ts files are evaluated during the build, and the output is static CSS. The README notes that none of the code in these files is included in your final bundle. You can think of TypeScript as the preprocessor where you would otherwise use Sass or Less.
The library also includes an optional runtime version for development and testing, and an optional API for dynamic runtime theming. The zero-runtime path does not compute styles from runtime input, so plan your styling around build-time values.
- Styles are generated at build time, like Sass or Less output.
- Class names are locally scoped, like CSS Modules.
- Optional runtime version and runtime theming API exist, separate from the zero-runtime path.
Other features to know about
Beyond classes and themes, the README lists locally scoped CSS variables, @keyframes and @font-face rules, and utilities for generating variable-based calc expressions. Styles are type-safe through CSSType.
Themes support simultaneous themes, so you can have more than one active without relying on globals. For higher-level, atomic styling built on top of vanilla-extract, the README points to Sprinkles, an official zero-runtime atomic CSS framework.
- Locally scoped CSS variables, @keyframes and @font-face rules.
- Theme system with support for simultaneous themes.
- Calc utilities for variable-based expressions.
- Type-safe styles via CSSType.
- Sprinkles for atomic CSS on top of vanilla-extract.
What people use it for
- Writing type-checked component styles in TypeScript for a React app.
- Defining a shared colour and font theme with CSS variables and reusing it across components.
- Shipping styles as static build-time CSS in a project that avoids a runtime styling cost.
- Using vanilla-extract with a framework such as React, or with no framework at all.
- Building a higher-level atomic style system on top of vanilla-extract with Sprinkles.
Frequently asked questions
Is vanilla-extract free to use?
vanilla-extract is released under the MIT licence, as stated in the repository. The README says the licence is MIT, so check the licence file in the repository for the full terms.
What do I need to install vanilla-extract?
The README lists Node.js and a build tool or bundler configured for vanilla-extract as prerequisites. The documentation site at vanilla-extract.style has setup guides for configuring your build tooling.
Does vanilla-extract work with React?
Yes. The README says it works with any front-end framework, or even without one, and it provides a CodeSandbox example using webpack and React.
Is vanilla-extract the same as CSS Modules?
Not exactly. Both scope class names locally, but vanilla-extract lets you write styles in TypeScript and adds CSS variables, themes and type-safe styles. The README describes it as CSS Modules-in-TypeScript with scoped CSS variables and more.
What are the alternatives to vanilla-extract?
Comparable projects named in this analysis are CSS Modules, Sass, Stitches and Linaria. Sass and Less generate styles at build time too, while Stitches and Linaria are CSS-in-JS options.
Why is my vanilla-extract code not applying styles?
The source does not cover troubleshooting steps. Check that your build tooling is configured for vanilla-extract as described in the documentation site, and that you import the exported class names from your .css.ts file.
New agent skills, repos and AI tools — every week
The best new skills and open-source projects, the fastest-growing repos, and one free prompt. Five minutes to read. Unsubscribe anytime.
Our verdict
vanilla-extract suits front-end developers and teams who want type-checked, build-time CSS with scoped class names and theme variables, and who are comfortable with a build setup. If you only write plain CSS, need styles driven by runtime user input, or do not want to configure a bundler, pick a simpler tool instead.
Install options & downloads