Documentation Index Fetch the complete documentation index at: https://mintlify.com/joe-bell/cva/llms.txt
Use this file to discover all available pages before exploring further.
Quickstart
Install CVA
npm i class-variance-authority
Create your first variant component
Define a button component with cva. Pass base classes as the first argument, then describe your variants, compoundVariants, and defaultVariants in the config object. import { cva } from "class-variance-authority" ;
const button = cva ([ "font-semibold" , "border" , "rounded" ], {
variants: {
intent: {
primary: [ "bg-blue-500" , "text-white" , "border-transparent" ],
secondary: [ "bg-white" , "text-gray-800" , "border-gray-400" ],
},
size: {
small: [ "text-sm" , "py-1" , "px-2" ],
medium: [ "text-base" , "py-2" , "px-4" ],
},
disabled: {
false: null ,
true: [ "opacity-50" , "cursor-not-allowed" ],
},
},
compoundVariants: [
{
intent: "primary" ,
disabled: false ,
class: "hover:bg-blue-600" ,
},
{
intent: "secondary" ,
disabled: false ,
class: "hover:bg-gray-100" ,
},
{
intent: "primary" ,
size: "medium" ,
class: "uppercase" ,
},
],
defaultVariants: {
intent: "primary" ,
size: "medium" ,
disabled: false ,
},
});
Calling the component resolves the correct class string: button ();
// => "font-semibold border rounded bg-blue-500 text-white border-transparent text-base py-2 px-4 hover:bg-blue-600 uppercase"
button ({ disabled: true });
// => "font-semibold border rounded bg-blue-500 text-white border-transparent text-base py-2 px-4 opacity-50 cursor-not-allowed uppercase"
button ({ intent: "secondary" , size: "small" });
// => "font-semibold border rounded bg-white text-gray-800 border-gray-400 text-sm py-1 px-2 hover:bg-gray-100"
Use of Tailwind CSS is optional. CVA works with any class-based styling approach, including plain CSS class names and CSS Modules.
Use it in your framework
cva returns a plain string, so it works anywhere you can set a class attribute.import { button } from "./button" ;
interface ButtonProps extends React . ButtonHTMLAttributes < HTMLButtonElement > {
intent ?: "primary" | "secondary" ;
size ?: "small" | "medium" ;
}
export function Button ({ intent , size , className , ... props } : ButtonProps ) {
return (
< button
className = { button ({ intent , size , className }) }
{ ... props }
/>
);
}
<!-- Resolve the class string server-side or in a build step -->
< button class = "font-semibold border rounded bg-blue-500 text-white border-transparent text-base py-2 px-4 hover:bg-blue-600 uppercase" >
Click me
</ button >
import { button } from "./components/button" ;
const primaryMedium = button ({ intent: "primary" , size: "medium" });
// => "font-semibold border rounded bg-blue-500 text-white border-transparent text-base py-2 px-4 hover:bg-blue-600 uppercase"
Extract variant types with VariantProps
Use the VariantProps utility type to derive the TypeScript prop types directly from your cva definition. This keeps your types and your variant config in sync automatically. import { cva , type VariantProps } from "class-variance-authority" ;
const button = cva ([ "font-semibold" , "border" , "rounded" ], {
variants: {
intent: {
primary: [ "bg-blue-500" , "text-white" , "border-transparent" ],
secondary: [ "bg-white" , "text-gray-800" , "border-gray-400" ],
},
size: {
small: [ "text-sm" , "py-1" , "px-2" ],
medium: [ "text-base" , "py-2" , "px-4" ],
},
},
defaultVariants: {
intent: "primary" ,
size: "medium" ,
},
});
// Extract the variant prop types
export type ButtonVariants = VariantProps < typeof button >;
// => { intent?: "primary" | "secondary"; size?: "small" | "medium" }
You can then use ButtonVariants in your component props interface: import { button , type ButtonVariants } from "./button" ;
interface ButtonProps
extends ButtonVariants ,
React . ButtonHTMLAttributes < HTMLButtonElement > {}
export function Button ({ intent , size , ... props } : ButtonProps ) {
return < button className = { button ({ intent , size }) } { ... props } /> ;
}
Next steps
Core concepts: Variants Learn about variants, compound variants, boolean variants, and default variants in depth.
API Reference Full reference for cva, cx, compose, defineConfig, and VariantProps.