Zero-runtimeStylesheets inTypeScript.

vanilla-extract.style · 2026-09-27 · by Long Nguyen ·generic
Zero-runtime Stylesheets-in-TypeScript.

Zero-runtimeStylesheets inTypeScript.

Search

Zero-runtime

Stylesheets in TypeScript.

Use TypeScript as your preprocessor. Write type‑safe, locally scoped classes, variables and themes, then generate static CSS files at build time.

`$

npm install @vanilla-extract/css`

Get started

GitHub

styles.css.ts

import { createTheme, style } from '@vanilla-extract/css';

export const [themeClass, vars] = createTheme({ color: { brand: 'blue', white: '#fff' }, space: { small: '4px', medium: '8px', } });

export const hero = style({ backgroundColor: vars.color.brandd, color: vars.color.white, padding: vars.space.large });

Type-safe static CSS

All styles generated at build time — just like Sass, LESS, etc, but with the power of TypeScript.

First-class theming

Create a single global theme or create multiple themes, all with type-safe token contracts.

Framework agnostic

Official integrations are provided for webpack, esbuild, Vite and Next.js.

Built for extension

Use libraries like Sprinkles, Recipes and Dessert Box — or create your own!

###

Leverage the full power of CSS & TypeScript

Write maintainable CSS at scale without sacrificing platform features. Variables, selectors, pseudo‑classes, media/feature/container queries, keyframes, font‑face and global styles are all supported.

styles.css.ts

import { style } from '@vanilla-extract/css';

export const className = style({ display: 'flex', flexDirection: 'column', selectors: { '&:nth-child(2n)': { background: 'aliceblue' } }, '@media': { 'screen and (min-width: 768px)': { flexDirection: 'row' } } });

Type-safe theming

Define themes with deeply nested token contracts, then let TypeScript do the heavy lifting. Never mess up a variable again.

styles.css.ts

import { createTheme, style } from '@vanilla-extract/css';

export const [themeClass, vars] = createTheme({ color: { brand: 'aquamarine', accent: 'honeydew', }, });

export const brandedSection = style({ backgroundColor: vars.color.brandd, });

Variables, the way they were intended

Define and consume variables without abstraction. All of your favourite CSS variable patterns can be translated to vanilla-extract.

styles.css.ts

import { style, createVar } from '@vanilla-extract/css';

const shadowColor = createVar();

export const shadow = style({ boxShadow: `0 0 10px ${shadowColor}`, selectors: { '.light &': { vars: { [shadowColor]: 'black' } }, '.dark &': { vars: { [shadowColor]: 'white' } }, }, });

Organise your styles with ease

Group style variants into separate collections, then look them up by name. No awkward naming conventions required.

styles.css.ts

import { styleVariants } from '@vanilla-extract/css';

export const background = styleVariants({ primary: { background: 'navy' }, secondary: { background: 'blue' }, tertiary: { background: 'aqua' }, });

export const color = styleVariants({ neutral: { color: 'black' }, secondary: { color: 'gray' }, link: { color: 'blue' }, });

Generate real stylesheets

Best-in-class developer experience without the runtime cost. Don’t ship a dynamic CSS engine to your users — ship regular CSS.

output.css

:root {
  --space-none__ya5b7b0: 0;
  --space-small__ya5b7b1: 4px;
  --space-medium__ya5b7b2: 8px;
  --space-large__ya5b7b3: 12px;
}

.Hero_container__1ldw6lo0 { padding: var(--space-medium__ya5b7b2); }

John Resig@jeresigvanilla-extract is super exciting - it’s scratching an itch that we have at @khanacademy, as we look to move off of Aphrodite to something that has better perf characteristics. We were thinking CSS Modules but this is even more ideal!

Andrey Okonetchnikov@okonetchnikovI really don’t want to rework my whole workshop but this is looking so good I almost have to 😅🤔

Jack Lo Russo@lorvssoI love this ✨ The first time I made a decision at work about CSS architecture, years ago now, CSS Modules was what I ended up recommending and implementing. This is CSS Modules for the new decade ❤️😍

Sasha Koss@kossnocorpvanilla-extract is the first CSS-in-JS library that excites me and convinces me to ditch CSS modules in favor of it. TypeScript support is superb 👌 Looking forward to rewriting my design system using it!

Like the monospace font in our code blocks? Check out monolisa.dev

Comments (0)

No comments yet