Skip to content

API Reference

This content is for Beta. Switch to the latest version for up-to-date documentation.

Builds a cva component

import { cva } from "cva";
const component = cva(options);
  1. options
    • base: the base class name (string, string[] or other clsx value)
    • variants: your variants schema
    • compoundVariants: variants based on a combination of previously defined variants
    • defaultVariants: set default values for previously defined variants
    • composes: shallow merge one or more other cva components into this one, as a single component or an array (see Composing Components)

A cva component function

Concatenates class names (an alias of clsx; swap in your own concatenator via cva/core)

import { cx } from "cva";
const className = cx(classes);

string

Extracts a plain-object schema (variant names, possible values, and default values) from a cva component. Use it to generate Storybook controls, documentation, or any other UI that reads a component’s variants without re-declaring them. See Utilities for use cases.

import { cva, getSchema } from "cva";
const button = cva({
base: "button",
variants: {
intent: {
primary: "button--primary",
secondary: "button--secondary",
},
disabled: {
true: "button--disabled",
false: "button--enabled",
},
},
defaultVariants: {
intent: "primary",
disabled: false,
},
});
getSchema(button);
// => {
// intent: { values: ["primary", "secondary"], defaultValue: "primary" },
// disabled: { values: [true, false], defaultValue: false },
// }

getSchema omits a variant that has no values (e.g. variants: { empty: {} }).

component: a component created by cva (including components composed via composes)

An object keyed by variant name. Each entry has:

  • values: a readonly array of the variant’s possible values
  • defaultValue: present only if the variant has a defaultVariants entry

The cva package is a preset: cva, cx, and getSchema wired up with clsx. cva/core is the same engine with nothing wired up, for rolling your own configuration.

Generate cva and cx functions based on your preferred configuration.

Store in a cva.config.ts file, and import across your project.

cva.config.ts
import { defineConfig } from "cva/core";
export const { cva, cx } = defineConfig(options);
  1. options
    • cx (required): the class name concatenator used by cva, cx, and compose. It owns the class name grammar entirely: cva assembles the authored values (composed component outputs, base, matched variant and compound variant values, class/className) and passes them through verbatim, one argument each, without interpreting them. The authoring surface adopts the concatenator’s parameter type automatically: pass twMerge and your variants are checked against tailwind-merge’s ClassNameValue (object syntax becomes a compile error), pass clsx or any function whose parameters don’t narrow further and you keep the full clsx-flavored ClassValue grammar. See Handling style conflicts for worked examples with tailwind-merge, cnfast, and clsx/lite.
    • hooks
      • onComplete (deprecated, use cx instead): returns a concatenated class string of all classes passed to cx or cva.

defineConfig also returns a deprecated compose function for migrating from class-variance-authority; use the composes property on cva instead. See What’s new?.

For backwards compatibility, defineConfig is still re-exported from cva (with cx optional, defaulting to clsx), but it’s deprecated there: import it from cva/core instead.