tailwind-variants

Typed Tailwind CSS variant API with slots, compound variants, and built-in class-conflict resolution

Library
npm
v3.3.1
3,291stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
68/100Good
Development Activity68
Maintenance60
Community52
Maturity52
Momentum40

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
85/100Excellent
Architecture88
Code Quality86
Innovation87
Learning Curve78

Tailwind Variants is a TypeScript-first variant API for Tailwind CSS that lets you define base styles, variants, compound variants, default variants, and component slots as a single typed configuration object. It layers built-in Tailwind class-conflict resolution on top of the variant system, so composing and overriding classes never produces duplicate or conflicting utility classes.

Framework-agnostic and dependency-light, it is used to build variant-driven design systems and component libraries — including HeroUI’s own component set — where a consistent, type-safe styling API matters across React, Vue, Svelte, or plain JS projects.

What You Get

  • A typed tv() API for defining base styles, variants, compound variants, default variants, and multi-slot components in one config object
  • Built-in Tailwind class-conflict resolution (via an internal tailwind-merge-compatible engine) on tv, createTV, cn, and cnMerge
  • A /lite entry point that drops conflict resolution for a smaller bundle when merging isn’t needed
  • cx, cn, and cnMerge utility functions for concatenating and optionally merging class names outside of tv()
  • Full TypeScript inference for variant props, slot names, and compound-variant conditions

Common Use Cases

  • Building a variant-driven design system where each component (button, card, input) exposes typed size/color/state props that map to Tailwind classes
  • Building multi-part components with slots (e.g. a card with header/body/footer slots) that share variant state across all slots
  • Replacing ad hoc clsx/template-literal class concatenation with a typed, cacheable resolver that also resolves Tailwind class conflicts
  • Powering component libraries (like HeroUI) that need a consistent styling API across many components and consumers using different bundlers or frameworks

Under The Hood

Architecture The package is layered: index.ts is a thin public API that wraps internal/tv.ts’s getTailwindVariants factory, which returns the tv/createTV functions. class-resolver.ts’s createClassResolver branches on a resolved.mode of "plain" | "variant" | "slots" into three specialized resolver closures (createPlainResolver, createVariantResolver, createSlotsResolver) that are built lazily on first invocation so constructing a tv() component stays cheap. resolve-options.ts eagerly parses the raw config into a ResolvedOptions descriptor and lazily compiles variants, compound variants, and compound slots on first call via compileResolvedOptions. cache.ts implements a bounded result cache (256-entry limit) keyed by a props fingerprint plus a compound-variants signature, with the very first invocation always skipping the cache to avoid caching cold-start artifacts. tw-merge.ts implements its own tailwind-merge-compatible engine (parse-class-name, class-group-utils, sort-modifiers) rather than depending on the tailwind-merge package at runtime for the default entry point.

Tech Stack TypeScript 5.6 in strict mode with exactOptionalPropertyTypes enabled. Built via tsup (esbuild-backed) into dual ESM (dist/index.js) and CJS (dist/index.cjs) bundles with generated .d.ts/.d.cts type files, plus separate lite and utils entry points declared through package.json exports. tailwind-merge and tailwindcss are optional peer dependencies (peerDependenciesMeta.optional: true), so the package still works when Tailwind isn’t present at runtime. The repo uses a pnpm workspace with .nvmrc/packageManager pinning, Biome 2.5 for linting instead of ESLint/Prettier, commitlint plus husky to enforce Conventional Commits, and bumpp + conventional-changelog to automate releases.

Code Quality 15 Vitest test files (cn.test.ts, create-tv.test.ts, merge-engine.test.ts, merge-parity.test.ts, tv-compound-slots.test.ts, tv-extend*.test.ts, tv-slots.test.ts, tv-tailwind-merge.test.ts, and more) cover the resolver modes, extension and composition behavior, and merge parity against upstream tailwind-merge semantics. A separate __types__ directory holds compile-time type tests (tsc -p .config/tsconfig.type-tests.json) that assert the public API’s inferred types for the core, slot, variant, and metadata APIs. strict: true plus exactOptionalPropertyTypes catch a class of undefined-vs-missing bugs at compile time. CI (ci.yml) runs alongside a dedicated benchmark.yml workflow that tracks performance regressions via tinybench.

API Design The public surface is deliberately small — tv, createTV, cn, cx, cnMerge, and defaultConfig — with tv() itself handling plain, variant, and slot-based components based on the shape of the config object passed in, so there’s no separate API to learn per mode. Slots and compound variants are expressed declaratively in the same config rather than requiring separate composition calls, and createTV mirrors tv exactly but pre-bound to custom config, keeping the mental model consistent. The project is documented at tailwind-variants.org with a runnable quick-start in the README and versioned migration guides (v1→v2, v2→v3) for breaking changes.

Used by 18 apps in this directory

TypeScript
75%
GPL 3.0

Bramble

Password Manager · Security · Authentication

315

Local-first, end-to-end encrypted password manager that syncs your vault directly between your own devices over a private peer-to-peer mesh — no server, no account, no cloud in the middle.

View details
73
Repo Health
84
Technical
72
Dependency
Built with
TypeScript75%
Updated today
Rust
67%
MIT

Bun

Developer Tools

95,452

An all-in-one JavaScript and TypeScript toolkit — one Rust-and-JavaScriptCore binary that replaces Node.js, npm, a bundler, and a test runner with faster equivalents.

View details
92
Repo Health
91
Technical
66
Dependency
Built with
Rust67%
C++19%
Updated today
JavaScript
99%
Other

ChartBrew

Analytics · Databases

4,041

Open-source reporting platform to build live dashboards from SQL, NoSQL, APIs, and SaaS tools with an AI assistant that creates charts from natural language.

View details
90
Repo Health
83
Technical
65
Dependency
Built with
JavaScript99%
Updated 6 days ago
TypeScript
45%
Other

Convex Backend

Developer Tools · Databases

12,394

Open-source reactive database that lets developers build live-updating apps with pure TypeScript, strong consistency, and real-time subscriptions—no separate API layer required.

View details
88
Repo Health
82
Technical
70
Dependency
Built with
TypeScript45%
Rust43%
Updated today
Java
34%
Apache 2.0

Enso

Analytics · Data Engineering · Low Code Platforms

7,437

A visual and textual programming platform for data prep and analysis where the node graph and the underlying Enso code are always perfectly in sync, built by an Alteryx co-founder on a GraalVM engine.

View details
70
Repo Health
90
Technical
62
Dependency
Built with
Java34%
TypeScript27%
Scala26%
Updated 1 weeks ago
TypeScript
72%
Other

Epicenter

Knowledge Management · Note Taking · Developer Tools

4,761

A local-first monorepo led by Whispering, an open-source speech-to-text app, built on an MIT toolkit that turns your data into plain Markdown and SQLite files you own instead of a database you rent.

View details
88
Repo Health
90
Technical
68
Dependency
Built with
TypeScript72%
Svelte15%
Updated today
JavaScript
52%
MIT

evidence

Analytics · Data Engineering

6,861

Turn SQL queries and markdown files into polished, interactive data apps and business intelligence reports — no drag-and-drop, no GUI, just code.

View details
65
Repo Health
79
Technical
65
Dependency
Built with
JavaScript52%
Svelte40%
Updated today
Python
63%
Other

Keep

Devops · Automation · Monitoring

12,224

The open-source AIOps and alert management platform that unifies 130+ monitoring tools into a single pane of glass with AI-powered correlation, deduplication, and workflow automation.

View details
91
Repo Health
79
Technical
67
Dependency
Built with
Python63%
TypeScript36%
Updated today
Svelte
49%

Kener

Monitoring · Devops

5,114

Stunning, self-hosted status pages with real-time uptime monitoring, incident management, and multi-channel notifications in a single Docker container.

View details
85
Repo Health
76
Technical
68
Dependency
Built with
Svelte49%
TypeScript47%
Updated 2 weeks ago

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search