UNPKG

classix

Version:

The fastest and tiniest utility for conditionally joining classNames.

140 lines (93 loc) β€’ 3.93 kB
![Banner](media/banner.jpg) # classix ![NPM version](https://img.shields.io/npm/v/classix?style=flat-square) ![Build](https://img.shields.io/github/actions/workflow/status/alexnault/classix/ci-and-publish.yml?branch=main&style=flat-square) ![Test coverage](https://img.shields.io/codecov/c/github/alexnault/classix?style=flat-square) ![Monthly downloads](https://img.shields.io/npm/dm/classix?style=flat-square) ![Size](https://img.shields.io/badge/dynamic/json?color=blue&label=size&query=$.size.uncompressedSize&url=https://deno.bundlejs.com?q=classix&style=flat-square) The [fastest](#performance) and [tiniest](#size) utility for conditionally joining classNames. ## Installation ```bash npm install classix ``` ## Usage Use any amount of string expressions and classix will join them like so: ```js import cx from "classix"; // or import { cx } from "classix"; cx("class1", "class2"); // => "class1 class2" cx("class1 class2", "class3", "class4 class5"); // => "class1 class2 class3 class4 class5" cx("class1", true && "class2"); // => "class1 class2" cx(false && "class1", "class2"); // => "class2" cx(true ? "class1" : "class2"); // => "class1" cx("class1", false ? "class2" : "class3"); // => "class1 class3" cx(...["class1", "class2", "class3"]); // => class1 class2 class3 cx( "flex", isPrimary ? "bg-primary-100" : "bg-secondary-100", isLarge ? "m-4 p-4" : "m-2 p-2", ); // => "flex bg-primary-100 m-2 p-2" *assuming isPrimary is true and isLarge is false ``` ## Comparison Compared to other libraries, classix only allows string expressions as arguments: ```js // 🚫 clsx({ "class-1": isPrimary }); // βœ… cx(isPrimary && "class-1"); // 🚫 clsx({ "class-1": isPrimary && isLarge, "class-2": !isPrimary || !isLarge }); // βœ… cx(isPrimary && isLarge ? "class-1" : "class-2"); ``` String expressions have a few benefits over objects: - A faster typing experience - A more intuitive syntax (conditions first) - `else` support through ternary operators What's more, by leveraging them, classix provides: - A simpler and consistent API - [A smaller library size](#size) - [Better performance](#performance) ### Size ![Size comparison chart](media/size.png) Sources: [classix](https://deno.bundlejs.com?q=classix), [clsx](https://deno.bundlejs.com?q=clsx), [classnames](https://deno.bundlejs.com?q=classnames) ### Performance ![Performance comparison chart](media/perf.png) Sources: Ran [benchmark](benchmark/) on an AMD Ryzen 5 5600x with Node 20. ## Highlights - Supports all major browsers - Supports all versions of Node.js - Works with both ES Modules and CommonJS - Zero dependencies - Fully typed with TypeScript - Fully tested - [Semver](https://semver.org/) compliant ## Migrating to classix If you are using `classnames` or `clsx`, you can migrate to `classix` by changing your `imports`: ```diff - import classnames from 'classnames'; + import cx from 'classix'; ``` And if you were using object arguments, you'll have to convert them to string arguments: ```diff - classnames({ 'class-1': cond1, 'class-2': cond2 }); + cx(cond1 && 'class-1', cond2 && 'class-2') ``` That's it! ## Some love ❀️ > "This looks great. I agree that the object notation is not great and not worth the perf hit." β€” @jmeistrich > "It looks good! I like the idea that you can’t pass objects and is simple and minimal. I will use it on my next application instead of classnames." β€” @m0ment98 > "Thank you for creating and maintaining this package! It is great." β€” @charkour ## Changelog For a list of changes and releases, see the [changelog](https://github.com/alexnault/classix/releases). ## Contributing Found a bug, have a question or looking to improve classix? Open an [issue](https://github.com/alexnault/classix/issues/new), start a [discussion](https://github.com/alexnault/classix/discussions/new) or submit a [PR](https://github.com/alexnault/classix/fork)!