Migration

Upgrade guides for moving between Tailwind Variants major versions, including v2 to v3 and the lite build split.

To v3.3.0

Drop tailwind-merge for TV

Conflict resolution ships in the default build. Install only Tailwind Variants unless your app calls tailwind-merge directly:

- npm i tailwind-variants tailwind-merge
+ npm i tailwind-variants

Keep tailwind-merge if you still use twMerge, extendTailwindMerge, or similar elsewhere.

Slots empty object

Passing slots: {} enables slot mode with an implicit base slot. Omit slots when you want a plain string return.

// Slot mode — returns { base: () => string }
const x = tv({ slots: {}, base: 'p-4' });

// String mode — omit slots
const y = tv({ base: 'p-4' });

cncnMerge for config

The v3.2.2 split still applies:

// Before
cn('px-2', 'px-4')({ twMerge: false });

// After
cnMerge('px-2', 'px-4')({ twMerge: false });
cn('px-2', 'px-4'); // string, default merge

Extended types

Extended component metadata now reflects merged variants, slots, and keys at runtime. Slotted components include the implicit base slot in types.


v3.2.0 → v3.2.2

cn returns a string

cn no longer accepts a config callback. Use cnMerge for custom merge behavior.

import { cn, cnMerge } from 'tailwind-variants';

cn('px-2', 'px-4'); // => "px-4"
cnMerge('px-2', 'px-4')({ twMerge: false }); // => "px-2 px-4"

v3.1.1 → v3.2.0

Replace cnBase with cx

- import { cnBase } from 'tailwind-variants';
+ import { cx } from 'tailwind-variants';

- cnBase('flex gap-2', className);
+ cx('flex gap-2', className);

cn defaults to merge

On the default build, cn resolves conflicting Tailwind classes automatically.


v2 → v3

Two builds

// Default — conflict resolution included (v3.3+)
import { tv, cn, cx } from 'tailwind-variants';

// Lite — no merge, ~80% smaller
import { tv, cx } from 'tailwind-variants/lite';

Removed APIs

  • responsiveVariants — use Tailwind responsive prefixes in class strings (Responsive)
  • withTv — use tv directly
  • Lazy merge loading — replaced by explicit default vs lite builds

Performance

v3 is significantly faster for merge operations. The default build includes merge; lite skips it entirely.

See Class Resolution and Releases for v3.3.0 details.

On this page