Defining config
defineConfig creates a custom set of cva, cx, and compose functions that share the same configuration. This lets you apply global transformations — such as merging conflicting Tailwind classes or adding a class prefix — without modifying every component individually.
The DefineConfigOptions interface
defineConfig accepts an optional options object with a hooks property:
hooks.onComplete
Called with the final concatenated class string after all variants, compound variants, and extra class/className props have been resolved. Whatever string you return replaces the output.
hooks["cx:done"]
Use case: integrating tailwind-merge globally
The most common use of defineConfig is wiring in tailwind-merge so that class conflicts are resolved everywhere, automatically:
lib/utils.ts
onComplete receives the fully-assembled class string, twMerge runs once per call regardless of how many variants or compound variants contributed to the output.
Use case: adding a class name prefix
If your design system requires a vendor prefix on all generated classes, you can apply it inonComplete:
lib/utils.ts
This example is illustrative. Real-world prefix requirements vary; adjust the transformation to match your system’s class naming scheme.
Re-exporting the configured instance
The recommended pattern is to create the configured instance once and re-export it so all components in your application use the samecva, cx, and compose:
Components that import from lib/utils automatically benefit from the configured hooks. You do not need to change any component-level code when the global configuration changes.