Skip to content

Quickstart ​

Install ​

sh
npm install variacss tailwindcss
sh
pnpm add variacss tailwindcss
sh
yarn add variacss tailwindcss
sh
bun add variacss tailwindcss

Define and register a component ​

Create varia.config.ts beside your CSS entrypoint:

varia.config.ts
ts
import { defineComponent } from 'variacss'
import { tailwindVaria } from 'variacss/tailwind'

const button = defineComponent('btn', {
  base: 'inline-flex rounded bg-blue-600 px-4 py-2 font-medium text-white',
  variants: {
    size: {
      lg: 'px-6 py-3 text-lg',
    },
  },
})

export default tailwindVaria({ components: [button] })

Load the plugin ​

Update your CSS entrypoint, keeping the imports in this order:

styles.css
css
@import "variacss/tailwind.css";
@import "tailwindcss";
@source not "./**/*.config.ts";
@plugin "./varia.config.ts";

The first import sets the order of Varia's CSS layers. @source not requires Tailwind 4.1+ and excludes definition files from source detection. This prevents Tailwind from also generating standalone utilities for strings in those files. Paths are relative to this stylesheet. Adjust the exclusion if you store definitions elsewhere.

Use the classes ​

html
<button type="button" class="btn btn-size-lg">Save</button>

See troubleshooting if styles are missing.

Editor support ​

Install Tailwind CSS IntelliSense for VS Code. It loads the plugin from your CSS entrypoint to suggest Varia classes and show their CSS on hover.

Development reload ​

With @tailwindcss/vite and Vite's default bundled config loader, import your registration module in vite.config.ts. Vite will restart when that module or its imported definitions change:

vite.config.ts
ts
import tailwindcss from '@tailwindcss/vite'
import { defineConfig } from 'vite'
import './src/varia.config.js'

export default defineConfig({
  plugins: [tailwindcss()],
})

Adjust the import path to your project and keep the stylesheet's @plugin directive.

Source detection ​

Tailwind detects Varia classes just like utilities. Use complete class names when choosing variants dynamically:

ts
const sizes = { base: 'btn', lg: 'btn btn-size-lg' }

For custom scan paths and safelisting, see Tailwind's source detection documentation.

Options ​

tailwindVaria accepts a components array and an optional prefix. Pass the objects returned by defineComponent without modifying them:

ts
export default tailwindVaria({ components: [button], prefix: 'tw' })
html
<button class="tw:btn tw:md:btn-size-lg">Save</button>

Keep utilities inside definitions unprefixed. A prefix must contain only lowercase ASCII letters.

If your stylesheet uses @import "tailwindcss" prefix(tw), also pass prefix: 'tw'. The plugin cannot read a prefix declared in CSS. It detects prefixes set through Tailwind's JavaScript configuration.

Released under the MIT License.