---
title: "API Reference"
description: "API reference for cva, cva/config, cva/tools, and cva/tailwindcss."
url: "https://cva.style/beta/api-reference/"
---

## `cva`

Builds a `cva` component

```ts
import { cva } from "cva";


const component = cva(options);
```

Treat component configuration as immutable

`cva` reads `options` during creation. Treat it, and everything it references, as immutable afterwards. To change a component’s configuration, create a new component.

A call reads only the props you pass it, plus the `cx` you gave [`defineConfig`](#defineconfig), which stays live. Getters with side effects, and changing the props object while the call is running, are unsupported.

### Parameters

1. `options`

   * `base`: the base class name (`string`, `string[]` or other [`clsx` value](https://github.com/lukeed/clsx#input))
   * `variants`: your [variants schema](https://cva.style/beta/getting-started/variants)
   * `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](https://cva.style/beta/getting-started/composing-components))

### Returns

A `cva` component function

## `cx`

Concatenates class names (an alias of [`clsx`](https://github.com/lukeed/clsx); swap in your own concatenator via [`cva/config`](#cvaconfig)).

```ts
import { cx } from "cva";


cx("button", "rounded");
```

Use cx for conditional class names

Use the included `cx` instead of adding `clsx` or `classnames` for conditional class names.

See the [`clsx` documentation](https://github.com/lukeed/clsx#usage) for examples of strings, arrays, and conditional objects. If you configure a different concatenator, follow its documentation for supported inputs; see [handling class conflicts](https://cva.style/beta/getting-started/installation#handling-class-conflicts) for the Tailwind CSS options.

### Parameters

* Zero or more class values. The preset accepts [`clsx` values](https://github.com/lukeed/clsx#input); `cva/config` uses the configured concatenator’s grammar

### Returns

`string`

## `cva/tailwindcss`

Custom Tailwind CSS variants, for use with or without `cva`. Import it after Tailwind CSS to add the `base:` variant.

### `base:`

Marks a utility as a component default. Ordinary utilities override `base:` utilities through the CSS cascade, and `base:` utilities still override browser defaults and Tailwind’s `base` and `components` layers.

See [cva/tailwindcss](https://cva.style/beta/getting-started/installation#cvatailwindcss) for setup and limitations.

## `cva/tools`

### `getSchema`

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 [Tools](https://cva.style/beta/getting-started/tools) for use cases.

```ts
import { cva } from "cva";
import { getSchema } from "cva/tools";


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 [internal variants](https://cva.style/beta/getting-started/variants#internal-variants) or variants that have no values (e.g. `variants: { empty: {} }`).

#### Parameters

`component`: a component created by `cva` (including components composed via [`composes`](#cva))

#### Returns

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

## `cva/config`

The `cva` package is a preset: [`cva`](#cva) and [`cx`](#cx) use `clsx`. `cva/config` is the same engine without a configured concatenator.

### `defineConfig`

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

```ts
import { defineConfig } from "cva/config";


export const { cva, cx } = defineConfig(options);
```

1. `options`

   * `cx` (**required**): the class name concatenator used by `cva` and `cx`

     * It owns the class name grammar: `cva` passes composed outputs, `base`, matched variant and compound-variant values, and `class`/`className` through verbatim, one argument each.
     * Custom callbacks must accept empty calls, variadic inputs, and composed component strings.
     * The authoring surface adopts its parameter type: `twMerge` rejects object syntax, while `clsx` keeps the full clsx-flavored `ClassValue` grammar.
     * See [Handling class conflicts](https://cva.style/beta/getting-started/installation#handling-class-conflicts) for CSS defaults, `cn`, and `tailwind-merge` examples.

### Advanced concatenators

Use [`clsx/lite`](https://github.com/lukeed/clsx#clsxlite) only when every authored value is a string and you do not need conflict resolution. Its runtime ignores arrays, objects, and numbers even though its published types accept them. Annotate a string-only wrapper so `cva` rejects those values too:

```ts
import { defineConfig } from "cva/config";
import { clsx as clsxLite } from "clsx/lite";


export const { cva, cx } = defineConfig({
  cx: (...inputs: string[]) => clsxLite(...inputs),
});
```
