npm.io
0.0.8 • Published 4 weeks agoCLI

cnfast

Licence
MIT
Version
0.0.8
Deps
0
Size
2.4 MB
Vulns
0
Weekly
0
Stars
1.1K

cnfast

version downloads

Fast drop-in replacement for cn.

cnfast runs 3.2x faster on average than clsx + tailwind-merge, up to 7x with tagged templates, with byte-identical output. Same API, no code changes.

import { cn } from "cnfast";

cn("px-2 py-1", isActive && "px-4", { "text-red-500": hasError });
// "py-1 px-4 text-red-500"

Install

npm install cnfast

Migrate an existing clsx, classnames, or tailwind-merge project in one command:

npx cnfast migrate

On a shadcn/ui project, add or replace your cn utility through the registry. This rewrites lib/utils.ts to re-export cnfast and installs the package:

npx shadcn@latest add aidenybai/cnfast/cn

Usage

Swap the shadcn/ui cn helper for cnfast:

// before
import { clsx, type ClassValue } from "clsx";
import { twMerge } from "tailwind-merge";
export const cn = (...inputs: ClassValue[]) => twMerge(clsx(inputs));

// after
export { cn } from "cnfast";

cnfast also exports clsx, twMerge, and twJoin.

Going even faster

As a tagged template, cn caches by call-site identity: a stable call site runs 2.6x faster than the cn(...) call form and 7x faster than clsx + tailwind-merge.

cn`px-2 px-4 ${isActive && "bg-blue-500"}`; // "px-4 bg-blue-500"

Comparing against cn

cnfast produces byte-identical output to clsx + tailwind-merge, then does that work faster. On a re-rendering call site, the tagged-template form pulls furthest ahead:

cnfast on a re-rendering call site, operations per second

Across the wider suite, operations per second on Bun, best-of-3:

Workload clsx + tailwind-merge cnfast Speedup
Cached re-render 2,192 ops/s 2,925 ops/s 1.33x
Merge engine, cold 473 ops/s 2,153 ops/s 4.55x
Component corpus 682 ops/s 2,421 ops/s 3.55x
Page render 3,047 ops/s 5,614 ops/s 1.84x
Live data grid 128 ops/s 231 ops/s 1.81x

Corpus and page rows are geometric means across 53 Tailwind apps and 8 captured pages; cached/cold/grid rows are single workloads. Across 65 workloads the geometric mean is 3.17x, with 0 mismatches over 113,291 real-world call groups. The bundle is 9.04 KB gzipped against 8.45 KB for the baseline.

cn runs once per element, so its cost scales with how much you render. Server-rendering a large page calls it across the whole tree, and a client app that re-renders often (data grids, virtualized tables, live dashboards) calls it thousands of times per second. A faster cn keeps those busy frames inside budget. On a small or rarely-updated page, the saving disappears into noise.

See the benchmark suite for the full breakdown and the architecture guide for how it works.

Credits

cnfast adapts MIT-licensed code from clsx (Luke Edwards) and tailwind-merge (Dany Castillo). See LICENSE.

License

MIT

Keywords