Using the cn() Utility
All components support className customization through the cn() utility, which intelligently merges Tailwind classes:
cn() function is a combination of clsx and tailwind-merge, ensuring proper class precedence:
lib/utils/index.ts
Understanding CVA Variants
Craft UI usesclass-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
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
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