Skip to content

Introduction

css-variants is a zero-dependency, type-safe CSS variant composition library for modern JavaScript. It helps you build powerful, flexible component style systems with variants.

  • Tiny & Fast — Zero dependencies, ~1KB minified+gzipped
  • 🔒 Type-Safe — First-class TypeScript support with complete type inference
  • 🧩 Flexible — Works with Tailwind, CSS modules, vanilla CSS, or inline styles
  • 👨‍💻 Developer-Friendly — Intuitive API inspired by CVA and Panda CSS
  • 🚀 Production-Ready — Battle-tested, fully tested, dual CJS/ESM builds

When building component libraries or design systems, you often need to manage multiple style variations for components. Without a structured approach, this can lead to:

  • Messy conditional class logic scattered throughout your components
  • Inconsistent styling patterns across your codebase
  • Poor TypeScript support for component props
  • Difficult maintenance as your component library grows

css-variants solves these problems by providing a clean, declarative API for defining component variants.

Create variants for single-element components using CSS class names:

import { cv } from 'css-variants'
const button = cv({
base: 'rounded font-medium',
variants: {
color: {
primary: 'bg-blue-600 text-white',
secondary: 'bg-gray-200 text-gray-900',
},
size: {
sm: 'px-3 py-1.5 text-sm',
lg: 'px-6 py-3 text-lg',
},
},
})

Create variants for multi-element components:

import { scv } from 'css-variants'
const card = scv({
slots: ['root', 'header', 'content', 'footer'],
base: {
root: 'rounded-lg border bg-white',
header: 'border-b p-4',
content: 'p-4',
footer: 'border-t p-4',
},
variants: {
variant: {
default: { root: 'border-gray-200' },
primary: { root: 'border-blue-200' },
},
},
})

Create variants using inline CSS styles for React’s style prop or similar:

import { sv } from 'css-variants'
const box = sv({
base: { display: 'flex', borderRadius: '8px' },
variants: {
size: {
sm: { padding: '8px' },
lg: { padding: '24px' },
},
},
})

A lightweight utility for merging class names:

import { cx } from 'css-variants'
cx('foo', 'bar') // => 'foo bar'
cx('foo', { active: true, disabled: false }) // => 'foo active'

Head over to the Installation guide to add css-variants to your project.