Skip to main content
Craft UI components are built to be flexible and extensible. This guide covers various approaches to customizing components for your specific needs.

Using the cn() Utility

All components support className customization through the cn() utility, which intelligently merges Tailwind classes:
The cn() function is a combination of clsx and tailwind-merge, ensuring proper class precedence:
lib/utils/index.ts

Understanding CVA Variants

Craft UI uses class-variance-authority (CVA) to define component variants. Here’s how the Button component defines its variants:
components/button/index.tsx

Adding Custom Variants

1

Create Extended Variants

Extend the existing variant definition with your custom variants:
components/custom-button.tsx
2

Create Component Interface

Define props using CVA’s VariantProps:
3

Build the Component

Implement the component using the variants:
4

Use Your Custom Variants

Wrapping Components

Create wrapper components to add custom functionality:
components/loading-button.tsx
Usage:

Compound Components

Build complex UIs by composing multiple Craft UI components:
components/feature-card.tsx

Extending Input Components

Create specialized input components with additional features:
components/search-input.tsx

Using Base UI’s render Prop

Craft UI components support Base UI’s render prop for complete control over rendering:

Customizing Composite Components

For components like Dialog or Tooltip that have multiple parts, customize each subcomponent:
components/custom-dialog.tsx

Real-World Example

Here’s a complete example combining multiple customization techniques:

Best Practices

Keep it semantic: When creating custom variants, use semantic names like "gradient" or "glass" rather than specific style descriptions.
Export variants: Always export your CVA variant definitions so they can be reused in other components.
When wrapping components, preserve the original component’s props by extending its type interface.

Next Steps

  • Theming - Customize colors and design tokens
  • Accessibility - Ensure your custom components are accessible