Skip to content

Migration from CVA

css-variants has a similar API to CVA (Class Variance Authority), making migration straightforward.

FeatureCVAcss-variants
Base stylesFirst argumentbase property
Compound class keyclassclassName
Custom mergerclass in callclassNameResolver in config
Slot variantsNot built-inscv function
Style variantsNot built-insv and ssv functions
import { cva } from 'class-variance-authority'
const button = cva('btn base-styles', {
variants: {
color: {
primary: 'bg-blue-600 text-white',
secondary: 'bg-gray-200 text-gray-900',
},
size: {
sm: 'px-3 py-1 text-sm',
lg: 'px-6 py-3 text-lg',
},
},
defaultVariants: {
color: 'primary',
size: 'sm',
},
})
import { cv } from 'css-variants'
const button = cv({
base: 'btn base-styles', // Move to 'base' property
variants: {
color: {
primary: 'bg-blue-600 text-white',
secondary: 'bg-gray-200 text-gray-900',
},
size: {
sm: 'px-3 py-1 text-sm',
lg: 'px-6 py-3 text-lg',
},
},
defaultVariants: {
color: 'primary',
size: 'sm',
},
})
const button = cva('btn', {
variants: { /* ... */ },
compoundVariants: [
{
color: 'primary',
size: 'lg',
class: 'shadow-lg', // CVA uses 'class'
},
],
})
const button = cv({
base: 'btn',
variants: { /* ... */ },
compoundVariants: [
{
color: 'primary',
size: 'lg',
className: 'shadow-lg', // css-variants uses 'className'
},
],
})
button({ color: 'primary', class: 'mt-4' })
button({ color: 'primary', className: 'mt-4' })
import { type VariantProps } from 'class-variance-authority'
const button = cva('btn', { /* ... */ })
type ButtonProps = VariantProps<typeof button>
const button = cv({ /* ... */ })
type ButtonProps = Parameters<typeof button>[0]

After migrating, you can take advantage of features not available in CVA:

import { scv } from 'css-variants'
const card = scv({
slots: ['root', 'header', 'content', 'footer'],
base: {
root: 'rounded-lg border',
header: 'p-4 border-b',
content: 'p-4',
footer: 'p-4 border-t',
},
variants: {
variant: {
default: { root: 'border-gray-200' },
primary: { root: 'border-blue-200' },
},
},
})
import { sv } from 'css-variants'
const box = sv({
base: {
display: 'flex',
borderRadius: '8px',
},
variants: {
size: {
sm: { padding: '8px' },
lg: { padding: '24px' },
},
},
})
  • Replace cva imports with cv from css-variants
  • Move first argument (base classes) to base property
  • Change class to className in compound variants
  • Change class to className in runtime overrides
  • Update VariantProps type extraction to use Parameters<typeof fn>[0]
  • (Optional) Convert multi-element components to use scv