Benchmarks
Performance matters. css-variants is engineered for speed, delivering exceptional runtime performance without sacrificing features.
Quick Summary
Section titled “Quick Summary”| Comparison | Simple Ops | Compound Variants | Complex Components | Slots |
|---|---|---|---|---|
| vs cva | ~1.1-1.3x | 3-4x faster | 2-7x faster | — |
| vs tailwind-variants | 3-5x faster | 5-7x faster | 10-11x faster | 3-7x faster |
css-variants vs class-variance-authority
Section titled “css-variants vs class-variance-authority”Direct comparison against the popular class-variance-authority (cva) library.
Basic Operations
Section titled “Basic Operations”| Test Case | css-variants | cva | Difference |
|---|---|---|---|
| Base class only | 23.2M ops/s | 21.2M ops/s | 1.09x faster |
| Single variant | 9.4M ops/s | 9.4M ops/s | Equal |
| Multiple variants | 5.1M ops/s | 4.7M ops/s | 1.07x faster |
| Boolean variants | 5.9M ops/s | 5.0M ops/s | 1.18x faster |
| className override | 20.7M ops/s | 15.7M ops/s | 1.31x faster |
Default Variants
Section titled “Default Variants”| Test Case | css-variants | cva | Difference |
|---|---|---|---|
| Defaults (no props) | 9.3M ops/s | 8.0M ops/s | 1.16x faster |
| Override one default | 8.2M ops/s | 6.3M ops/s | 1.31x faster |
| With className | 8.4M ops/s | 6.6M ops/s | 1.27x faster |
Compound Variants
Section titled “Compound Variants”This is where css-variants really shines:
| Test Case | css-variants | cva | Difference |
|---|---|---|---|
| No match | 4.2M ops/s | 1.1M ops/s | 3.70x faster |
| Single match | 4.1M ops/s | 1.0M ops/s | 3.92x faster |
| Multiple matches | 3.8M ops/s | 0.9M ops/s | 4.24x faster |
Complex Real-World Components
Section titled “Complex Real-World Components”Testing a production-ready button component with 6 variant options and compound rules:
| Test Case | css-variants | cva | Difference |
|---|---|---|---|
| With defaults | 8.1M ops/s | 3.4M ops/s | 2.40x faster |
| With overrides | 5.1M ops/s | 0.7M ops/s | 6.93x faster |
css-variants vs tailwind-variants
Section titled “css-variants vs tailwind-variants”Comparison against tailwind-variants, using its lightweight /lite build.
Basic Operations
Section titled “Basic Operations”| Test Case | css-variants | tailwind-variants | Difference |
|---|---|---|---|
| Base class only | 23.1M ops/s | 6.4M ops/s | 3.59x faster |
| Single variant | 9.9M ops/s | 2.2M ops/s | 4.52x faster |
| Multiple variants | 4.8M ops/s | 1.1M ops/s | 4.58x faster |
| Boolean variants | 5.8M ops/s | 1.6M ops/s | 3.57x faster |
| className override | 21.4M ops/s | 3.9M ops/s | 5.47x faster |
Default Variants
Section titled “Default Variants”| Test Case | css-variants | tailwind-variants | Difference |
|---|---|---|---|
| Defaults (no props) | 8.6M ops/s | 1.4M ops/s | 6.04x faster |
| Override one default | 8.6M ops/s | 1.4M ops/s | 6.35x faster |
| With className | 8.4M ops/s | 2.1M ops/s | 4.07x faster |
Compound Variants
Section titled “Compound Variants”| Test Case | css-variants | tailwind-variants | Difference |
|---|---|---|---|
| No match | 4.2M ops/s | 0.6M ops/s | 6.60x faster |
| Single match | 4.0M ops/s | 0.7M ops/s | 5.43x faster |
| Multiple matches | 3.8M ops/s | 0.7M ops/s | 5.57x faster |
Complex Real-World Components
Section titled “Complex Real-World Components”| Test Case | css-variants | tailwind-variants | Difference |
|---|---|---|---|
| With defaults | 8.1M ops/s | 0.8M ops/s | 10.39x faster |
| With overrides | 5.2M ops/s | 0.5M ops/s | 11.05x faster |
Slot-Based Components: scv vs tailwind-variants
Section titled “Slot-Based Components: scv vs tailwind-variants”Comparing css-variants’ scv (slot class variants) against tailwind-variants’ slots feature.
Basic Slots
Section titled “Basic Slots”| Test Case | css-variants (scv) | tailwind-variants | Difference |
|---|---|---|---|
| Base slots (2 slots) | 11.4M ops/s | 2.1M ops/s | 5.33x faster |
| Single variant (2 slots) | 3.9M ops/s | 1.2M ops/s | 3.25x faster |
| Multiple slots (4 slots) | 2.2M ops/s | 0.6M ops/s | 3.79x faster |
| Multiple variants (4 slots) | 1.8M ops/s | 0.4M ops/s | 4.67x faster |
| No variants (optimized) | 9.3M ops/s | 2.0M ops/s | 4.59x faster |
Default Variants with Slots
Section titled “Default Variants with Slots”| Test Case | css-variants (scv) | tailwind-variants | Difference |
|---|---|---|---|
| Defaults (no props) | 2.8M ops/s | 0.7M ops/s | 3.95x faster |
| Override one default | 2.7M ops/s | 0.8M ops/s | 3.52x faster |
| With classNames | 2.8M ops/s | 1.0M ops/s | 2.75x faster |
Compound Variants with Slots
Section titled “Compound Variants with Slots”| Test Case | css-variants (scv) | tailwind-variants | Difference |
|---|---|---|---|
| No match | 1.8M ops/s | 0.3M ops/s | 6.04x faster |
| Single match | 1.7M ops/s | 0.2M ops/s | 7.45x faster |
| Multiple matches | 1.6M ops/s | 0.2M ops/s | 7.47x faster |
Complex Slot Components
Section titled “Complex Slot Components”| Test Case | css-variants (scv) | tailwind-variants | Difference |
|---|---|---|---|
| Card (7 slots, defaults) | 1.6M ops/s | 0.3M ops/s | 6.26x faster |
| Card (7 slots, overrides) | 0.8M ops/s | 0.1M ops/s | 7.32x faster |
| Stress test (8 slots) | 1.2M ops/s | 0.3M ops/s | 3.44x faster |
Why css-variants is Faster
Section titled “Why css-variants is Faster”1. Optimized Data Structures
Section titled “1. Optimized Data Structures”css-variants uses simple JavaScript objects and arrays with minimal indirection. No complex class instances or prototype chains.
2. Early Exit Strategies
Section titled “2. Early Exit Strategies”When checking compound variants, css-variants exits as soon as a mismatch is found, avoiding unnecessary comparisons.
3. Pre-computation
Section titled “3. Pre-computation”Variant configurations are analyzed at creation time, not at runtime. The returned function is optimized for the specific configuration.
4. Minimal String Operations
Section titled “4. Minimal String Operations”Class strings are concatenated efficiently using a lightweight cx utility, avoiding expensive regex operations or repeated string allocations.
5. No Runtime Dependencies
Section titled “5. No Runtime Dependencies”Zero external dependencies means no additional function call overhead or module resolution costs.
Running Benchmarks Yourself
Section titled “Running Benchmarks Yourself”Clone the repository and run the benchmarks on your machine:
git clone https://github.com/timphandev/css-variants.gitcd css-variantsyarn installcd internal/benchmarkyarn startResults are saved to internal/benchmark/dist/benchmark.json.
Benchmark Configuration
Section titled “Benchmark Configuration”- Framework: Vitest Bench (using tinybench)
- Duration: 500ms minimum per test
- Warmup: Automatic by tinybench
- Environment: Node.js
Methodology
Section titled “Methodology”All benchmarks follow these principles:
- Fair comparison: Identical configurations for both libraries
- Isolated setup: Variant configs created outside bench blocks (not measured)
- Real-world scenarios: Test cases mirror actual production usage patterns
- Statistical rigor: Multiple iterations with standard deviation and percentile metrics
Last updated: December 2025