Extending components
CVA provides several ways to extend or build on top of existing components: ad-hoc class overrides via theclass prop, specialized components that share a base variant definition, and the compose helper for merging two CVA components into one.
Ad-hoc overrides with the class prop
Every CVA component accepts an optional class or className prop. Classes passed here are appended after all resolved variant classes, making them the simplest way to add one-off styles:
components/button.ts
class and className are mutually exclusive. Passing both at once is a TypeScript error.Creating a specialized variant
When you want a component that always sets a specific variant value — for example, aPrimaryButton that is always intent: "primary" — extract the variant props with VariantProps and re-use the same cva definition:
components/button.ts
VariantProps infers the full set of variant props from the cva definition, giving you a type-safe foundation to build on.
Composing two CVA components with compose
The compose helper (available in the cva package) merges two or more CVA components into a single callable. The returned function accepts the union of all variant props and resolves each component’s classes:
components/card.ts
card function accepts margin, padding, and shadow as a single flat props object. compose distributes the props to each component internally.
compose is exported from the cva package (v1+). It is not available in the legacy class-variance-authority package.Choosing an approach
class prop
One-off overrides at the call site. No new abstraction needed.
VariantProps specialization
Lock in one or more variants. Keeps the base definition as the source of truth.
compose
Merge independent variant sets into one component. Requires
cva v1+.cx-based manual composition approach, see Composing components.