FAQ

Answers to common questions about licensing, default vs lite builds, tailwind-merge, slots, TypeScript, and frameworks.

Is Tailwind Variants free?

Yes. MIT licensed. Use it in commercial and open-source projects.

Default build or lite?

Default (tailwind-variants) when you want automatic Tailwind conflict resolution — included since v3.3, no extra install.

Lite (tailwind-variants/lite) when bundle size matters and you do not need merge (~80% smaller).

import { tv } from 'tailwind-variants';       // merge on
import { tv } from 'tailwind-variants/lite';  // merge off

Do I need tailwind-merge?

No — not for Tailwind Variants on v3.3+. Merge is built into the default build.

Keep tailwind-merge only if your app imports it directly (twMerge, extendTailwindMerge, etc.).

Why slots: {}?

An explicit empty slots object enables slot mode with a single implicit base slot:

const x = tv({ slots: {}, base: 'p-4' });
x().base(); // slot function

const y = tv({ base: 'p-4' });
y(); // plain string — omit slots entirely

Omit slots when you do not need slot functions.

cn vs cx vs cnMerge?

Merge conflictsReturnsBuild
cxNoStringDefault + lite
cnYes (default config)StringDefault only
cnMergeYes (custom config)CurriedDefault only
cx('text-blue-500', 'text-red-500');  // both classes
cn('text-blue-500', 'text-red-500');  // "text-red-500"
cnMerge('px-2', 'px-4')({ twMerge: false }); // "px-2 px-4"

Use cn for everyday merge. Use cx in lite or when classes cannot conflict. Use cnMerge when you need per-call config.

Framework support?

Tailwind Variants is framework-agnostic. It returns class strings — use with any framework or vanilla JS. See Quick Start for binding examples.

Can I extend multiple components?

One extend parent per recipe. Chain extends or compose class strings manually for multiple bases.

TypeScript not inferring variants?

Define variants inline inside tv, or use as const on external objects:

const variants = { primary: 'bg-zinc-900 text-white', secondary: 'bg-zinc-100' } as const;
const button = tv({ variants: { variant: variants } });

Still stuck?

Ask in Discord or open a GitHub Discussion.

On this page