New Research: Supply Chain Attack on Axios Pulls Malicious Dependency from npm.Details →
Socket
Book a DemoSign in
Socket

css-variants

Package Overview
Dependencies
Maintainers
1
Versions
30
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

css-variants

Lightweight helpers to compose class names and inline styles using variants. Zero runtime deps, small bundle, and first-class TypeScript support.

latest
Source
npmnpm
Version
2.3.5
Version published
Weekly downloads
4.9K
-4.47%
Maintainers
1
Weekly downloads
 
Created
Source

css-variants

Fastest CSS variant library for JavaScript and TypeScript

Type-safe alternative to CVA (Class Variance Authority) and tailwind-variants. ~1KB gzipped. 3-11x faster. Zero dependencies.

npm version Bundle Size TypeScript License: MIT

Documentation · API Reference · Comparison

What is css-variants?

css-variants is a JavaScript library for managing CSS class variants with full TypeScript support. Define style variations (color, size, state) declaratively and get the correct CSS classes at runtime.

Works with Tailwind CSS, vanilla CSS, CSS Modules, or any styling solution.

Installation

npm install css-variants
pnpm add css-variants
yarn add css-variants

Quick Start

cv() — Class Variants

Create type-safe variants for single-element components:

import { cv } from 'css-variants'

const button = cv({
  base: 'font-semibold rounded-lg transition-colors',
  variants: {
    color: {
      primary: 'bg-blue-600 text-white hover:bg-blue-700',
      secondary: 'bg-gray-200 text-gray-900 hover:bg-gray-300',
    },
    size: {
      sm: 'px-3 py-1.5 text-sm',
      md: 'px-4 py-2 text-base',
      lg: 'px-6 py-3 text-lg',
    },
  },
  defaultVariants: {
    color: 'primary',
    size: 'md',
  },
})

button()                                // Uses defaults
button({ color: 'secondary', size: 'lg' }) // Override variants
button({ className: 'w-full' })         // Add custom classes

scv() — Slot Class Variants

Create variants for multi-element components (cards, modals, dropdowns):

import { scv } from 'css-variants'

const card = scv({
  slots: ['root', 'header', 'body', 'footer'],
  base: {
    root: 'rounded-xl border shadow-sm',
    header: 'px-6 py-4 border-b font-semibold',
    body: 'px-6 py-4',
    footer: 'px-6 py-3 bg-gray-50',
  },
  variants: {
    variant: {
      default: { root: 'bg-white border-gray-200' },
      primary: { root: 'bg-blue-50 border-blue-200' },
    },
  },
})

const classes = card({ variant: 'primary' })
// classes.root   → 'rounded-xl border shadow-sm bg-blue-50 border-blue-200'
// classes.header → 'px-6 py-4 border-b font-semibold'

sv() — Style Variants

Create variants that return CSS style objects:

import { sv } from 'css-variants'

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

<div style={box({ size: 'lg' })} />

cx() — Class Merger

Lightweight clsx alternative for conditional class merging:

import { cx } from 'css-variants'

cx('btn', 'btn-primary')              // 'btn btn-primary'
cx('btn', isActive && 'active')       // 'btn active' or 'btn'
cx('btn', { disabled: isDisabled })   // 'btn disabled' or 'btn'

Why css-variants?

Featurecss-variantsCVAtailwind-variants
Bundle size~1KB~2KB~5KB
PerformanceBaseline3-7x slower5-11x slower
Slot variantsBuilt-inNoYes
Style variantsBuilt-inNoNo
Dependencies011

Tailwind CSS Integration

Use with tailwind-merge for class conflict resolution:

import { cv, cx } from 'css-variants'
import { twMerge } from 'tailwind-merge'

const button = cv({
  base: 'px-4 py-2 rounded',
  variants: {
    size: { lg: 'px-6 py-3' },
  },
  classNameResolver: (...args) => twMerge(cx(...args)),
})

Full Tailwind guide →

Framework Examples

React

import { cv } from 'css-variants'

const button = cv({
  base: 'rounded font-medium',
  variants: {
    variant: { primary: 'bg-blue-600 text-white' },
  },
})

type ButtonProps = React.ButtonHTMLAttributes<HTMLButtonElement> &
  Parameters<typeof button>[0]

function Button({ variant, className, ...props }: ButtonProps) {
  return <button className={button({ variant, className })} {...props} />
}

Vue

<script setup lang="ts">
import { cv } from 'css-variants'

const button = cv({
  base: 'rounded font-medium',
  variants: {
    variant: { primary: 'bg-blue-600 text-white' },
  },
})

defineProps<{ variant?: 'primary' }>()
</script>

<template>
  <button :class="button({ variant })"><slot /></button>
</template>

Migrate from CVA

- import { cva } from 'class-variance-authority'
+ import { cv } from 'css-variants'

- const button = cva('base-classes', {
+ const button = cv({
+   base: 'base-classes',
    variants: { /* same */ },
    compoundVariants: [
-     { color: 'primary', class: 'extra' }
+     { color: 'primary', className: 'extra' }
    ],
  })

Full migration guide →

API Reference

FunctionDescription
cv()Class variants for single-element components
scv()Slot class variants for multi-element components
sv()Style variants for inline CSS style objects
ssv()Slot style variants for multi-element inline styles
cx()Class merger utility (like clsx)

Documentation

css-variants.vercel.app

License

MIT © Tim Phan

Keywords

javascript

FAQs

Package last updated on 18 Feb 2026

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts