Quick Start
Install Tailwind Variants, choose default or lite, create your first tv recipe, and set up editor IntelliSense.
Install
npm install tailwind-variantsConflict resolution is included in the default build. You do not need tailwind-merge unless your app calls it directly elsewhere.
For the lite build (no merge, smaller bundle):
import { tv } from "tailwind-variants/lite";Your first component
Define a recipe with tv, then call it like a function. Defaults keep call sites short; pass props only when you need to diverge.
import { tv } from 'tailwind-variants';const button = tv({ base: 'inline-flex cursor-pointer items-center justify-center rounded-full font-medium select-none transition-colors', variants: { variant: { primary: 'bg-zinc-900 text-white hover:bg-zinc-800', secondary: 'border border-zinc-300 bg-zinc-50 text-zinc-900 hover:bg-zinc-100', tertiary: 'text-zinc-700 hover:bg-zinc-200/70 hover:text-zinc-950' }, size: { sm: 'h-8 px-3 text-sm', md: 'h-10 px-4 text-sm' } }, defaultVariants: { variant: 'primary', size: 'md' }});<button className={button()}>Default button</button><button className={button({ variant: 'secondary', size: 'sm' })}> Click me</button><button className={button({ class: 'w-full' })}>Full width</button>Editor setup
VS Code IntelliSense
So Tailwind CSS IntelliSense can complete classes inside tv strings, add this to your VS Code settings:
{
"tailwindCSS.experimental.classRegex": [
["tv\\(([^)]*)\\)", "[\"'`]([^\"'`]*).*?[\"'`]"]
]
}Prettier
If you use prettier-plugin-tailwindcss, include tv in the function list so class order stays consistent:
// prettier.config.js
module.exports = {
plugins: ["prettier-plugin-tailwindcss"],
tailwindFunctions: ["tv", "cn", "cx"],
};Framework agnostic
Tailwind Variants is framework-agnostic. Use the class string with any framework or vanilla JS:
import { tv } from "tailwind-variants";
const button = tv({
base: "inline-flex cursor-pointer items-center justify-center rounded-md px-4 py-2 text-sm font-medium select-none",
variants: {
color: {
primary: "bg-blue-600 text-white",
secondary: "bg-zinc-200 text-zinc-900",
},
},
defaultVariants: {
color: "primary",
},
});React
<button className={button({ color: "primary" })}>Save</button>Vue
<button :class="button({ color: 'primary' })">Save</button>Svelte
<button class={button({ color: 'primary' })}>Save</button>Solid
<button class={button({ color: "primary" })}>Save</button>Angular
<button [class]="button({ color: 'primary' })">Save</button>Vanilla
element.className = button({ color: "primary" });