{"_id":"cn","_rev":"20-53ecec6f194c9fd56cc6ff6535efc2cc","name":"cn","dist-tags":{"latest":"0.2.4"},"versions":{"0.1.0":{"name":"cn","version":"0.1.0","keywords":["chuck","norris"],"author":{"name":"Djordje Lukic"},"license":"MIT","_id":"cn@0.1.0","maintainers":[{"name":"rumpl","email":"lukic.djordje@gmail.com"}],"bin":{"cn":"bin/cn"},"dist":{"shasum":"bb288fb634590681d227773ed53e8ff9219c670c","tarball":"https://registry.npmjs.org/cn/-/cn-0.1.0.tgz","integrity":"sha512-1gf3Z3u31y+K4Cwo7oDSNQS05nm/6PnNGheQ6HLy1Hx0kqanIeoN6x0Bigsx/jNJDWEhHjANk5qJOZRiG3lhrw==","signatures":[{"sig":"MEUCIGvEmnYIWnQFS95Un4zHfJGswnbG5KkxLd3N18Jw59tdAiEA91vG+gHUMrYq1Bv9dLNDkLpU6rRgsRMVqIsnXVUW9vg=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}]},"main":"bin/cn","_from":".","_npmUser":{"name":"rumpl","email":"lukic.djordje@gmail.com"},"repository":{"url":"git://github.com/rumpl/cn.git","type":"git"},"_npmVersion":"1.2.15","description":"Chuck Norris jokes whenever you need one","directories":{},"dependencies":{"request":"~2.21.0"}},"0.1.1":{"name":"cn","version":"0.1.1","keywords":["chuck","norris"],"author":{"name":"Djordje Lukic"},"license":"MIT","_id":"cn@0.1.1","maintainers":[{"name":"rumpl","email":"lukic.djordje@gmail.com"}],"bin":{"cn":"bin/cn"},"dist":{"shasum":"d97926f6ca5a4792f1af2f336a8eff6abfaed021","tarball":"https://registry.npmjs.org/cn/-/cn-0.1.1.tgz","integrity":"sha512-PkWPdg4L4aQEwqqkGzMclTdHlstGzBg773gBtsUCHqXrawQ8wQHf/490Rw2hXPaoI7QXYbCgI67Jfe25TjxLGw==","signatures":[{"sig":"MEUCIF1qBde7tXGHBx+//iz9c6jv4D5v/6MF22lVIlgvCh3aAiEA9MA9GbExVNxSVM5uFXlina0wzoOVqaLXjT/P9G9Es3w=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}]},"main":"bin/cn","_from":".","_npmUser":{"name":"rumpl","email":"lukic.djordje@gmail.com"},"repository":{"url":"git://github.com/rumpl/cn.git","type":"git"},"_npmVersion":"1.2.15","description":"Chuck Norris jokes whenever you need one","directories":{},"dependencies":{"string":"~1.4.0","request":"~2.21.0"}},"0.2.0":{"name":"cn","version":"0.2.0","keywords":["tailwind","tailwindcss","tailwind-merge","clsx","classnames","cn","class","merge"],"license":"MIT","_id":"cn@0.2.0","maintainers":[{"name":"shadcn","email":"m@shadcn.com"}],"homepage":"https://github.com/shadcn-ui/cn#readme","bugs":{"url":"https://github.com/shadcn-ui/cn/issues"},"bin":{"cn":"bin/cn.mjs"},"dist":{"shasum":"8e4e309def048cfb06c6b0dd540a1e89d552e955","tarball":"https://registry.npmjs.org/cn/-/cn-0.2.0.tgz","fileCount":38,"integrity":"sha512-V5/cy/bY90vmVLIVl/pmGp2HCpAh9w73dSrs7HpyHsddr6R4SWRJ7I1+gVd+bZRyo9qgBgtW3sh3Y8cpd6DEew==","signatures":[{"sig":"MEQCICwT2LsUus0vXXbZKPrcecmxD8QYN9LPjdS2cujk2R7wAiBXFdNcIyHdH8k2q6PwkoccMgaGVHfJhEDdgiEyriBHaw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":319532},"main":"./dist/index.cjs","type":"module","_from":"file:cn-0.2.0.tgz","types":"./dist/index.d.ts","module":"./dist/index.js","engines":{"node":">=20"},"exports":{".":{"import":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"require":{"types":"./dist/index.d.cts","default":"./dist/index.cjs"}},"./lite":{"import":{"types":"./dist/lite.d.ts","default":"./dist/lite.js"},"require":{"types":"./dist/lite.d.cts","default":"./dist/lite.cjs"}},"./config":{"import":{"types":"./dist/config.d.ts","default":"./dist/config.js"},"require":{"types":"./dist/config.d.cts","default":"./dist/config.cjs"}},"./engine":{"import":{"types":"./dist/engine.d.ts","default":"./dist/engine.js"},"require":{"types":"./dist/engine.d.cts","default":"./dist/engine.cjs"}},"./tables":{"import":{"types":"./dist/tables.d.ts","default":"./dist/tables.js"},"require":{"types":"./dist/tables.d.cts","default":"./dist/tables.cjs"}},"./compiler":{"import":{"types":"./dist/compiler.d.ts","default":"./dist/compiler.js"},"require":{"types":"./dist/compiler.d.cts","default":"./dist/compiler.cjs"}}},"scripts":{"build":"tsdown","compile-tables":"node scripts/compile-tables.mjs"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:189af90d-83b1-4f61-8b8e-0e7b7da7a8ff"}},"_resolved":"/tmp/9dc5f2416bbff8f681107c368f0fcc6f/cn-0.2.0.tgz","_integrity":"sha512-V5/cy/bY90vmVLIVl/pmGp2HCpAh9w73dSrs7HpyHsddr6R4SWRJ7I1+gVd+bZRyo9qgBgtW3sh3Y8cpd6DEew==","repository":{"url":"git+https://github.com/shadcn-ui/cn.git","type":"git","directory":"packages/cn"},"_npmVersion":"11.19.1","description":"Fast, small, compiled class-name merging for Tailwind CSS. Drop-in replacement for clsx + tailwind-merge.","directories":{},"sideEffects":false,"_nodeVersion":"24.19.0","_hasShrinkwrap":false,"devDependencies":{"tsdown":"^0.12.0","typescript":"^5.7.0"},"_npmOperationalInternal":{"tmp":"tmp/cn_0.2.0_1788265063708_0.07615272186693534","host":"s3://npm-registry-packages-npm-production"}},"0.2.1":{"name":"cn","version":"0.2.1","keywords":["tailwind","tailwindcss","tailwind-merge","clsx","classnames","cn","class","merge"],"license":"MIT","_id":"cn@0.2.1","maintainers":[{"name":"shadcn","email":"m@shadcn.com"}],"homepage":"https://github.com/shadcn-ui/cn#readme","bugs":{"url":"https://github.com/shadcn-ui/cn/issues"},"bin":{"cn":"bin/cn.mjs"},"dist":{"shasum":"cf3b90d68487bec39938bb007dac38a7974d4bc1","tarball":"https://registry.npmjs.org/cn/-/cn-0.2.1.tgz","fileCount":38,"integrity":"sha512-nXkKvwTTpumfnYY3zmu4bd1b35LcuoHwHXnjJp78HYRd2Y/fMO4WvOm9m8/9VBIGZNdTzjw+yJSgpL8nJhnTSw==","signatures":[{"sig":"MEQCIH6F/okg2gl10zRwFL4uFhlRrDorMNvY8UE5mKgugyMoAiB4RdNc50f9guFYA16NdftTvQN7Ttj0RFt8E5UCdbnLBg==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/cn@0.2.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":320527},"main":"./dist/index.cjs","type":"module","_from":"file:cn-0.2.1.tgz","types":"./dist/index.d.ts","module":"./dist/index.js","engines":{"node":">=20"},"exports":{".":{"import":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"require":{"types":"./dist/index.d.cts","default":"./dist/index.cjs"}},"./lite":{"import":{"types":"./dist/lite.d.ts","default":"./dist/lite.js"},"require":{"types":"./dist/lite.d.cts","default":"./dist/lite.cjs"}},"./config":{"import":{"types":"./dist/config.d.ts","default":"./dist/config.js"},"require":{"types":"./dist/config.d.cts","default":"./dist/config.cjs"}},"./engine":{"import":{"types":"./dist/engine.d.ts","default":"./dist/engine.js"},"require":{"types":"./dist/engine.d.cts","default":"./dist/engine.cjs"}},"./tables":{"import":{"types":"./dist/tables.d.ts","default":"./dist/tables.js"},"require":{"types":"./dist/tables.d.cts","default":"./dist/tables.cjs"}},"./compiler":{"import":{"types":"./dist/compiler.d.ts","default":"./dist/compiler.js"},"require":{"types":"./dist/compiler.d.cts","default":"./dist/compiler.cjs"}}},"scripts":{"build":"tsdown","compile-tables":"node scripts/compile-tables.mjs"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:189af90d-83b1-4f61-8b8e-0e7b7da7a8ff"}},"_resolved":"/tmp/2b395e834733236186b41ff501d2005b/cn-0.2.1.tgz","_integrity":"sha512-nXkKvwTTpumfnYY3zmu4bd1b35LcuoHwHXnjJp78HYRd2Y/fMO4WvOm9m8/9VBIGZNdTzjw+yJSgpL8nJhnTSw==","repository":{"url":"git+https://github.com/shadcn-ui/cn.git","type":"git","directory":"packages/cn"},"_npmVersion":"11.19.1","description":"Fast, small, compiled class-name merging for Tailwind CSS. Drop-in replacement for clsx + tailwind-merge.","directories":{},"sideEffects":false,"_nodeVersion":"24.19.0","_hasShrinkwrap":false,"devDependencies":{"tsdown":"^0.12.0","typescript":"^5.7.0"},"_npmOperationalInternal":{"tmp":"tmp/cn_0.2.1_1788280980515_0.02061554996115489","host":"s3://npm-registry-packages-npm-production"}},"0.2.2":{"name":"cn","version":"0.2.2","keywords":["tailwind","tailwindcss","tailwind-merge","clsx","classnames","cn","class","merge"],"license":"MIT","_id":"cn@0.2.2","maintainers":[{"name":"shadcn","email":"m@shadcn.com"}],"homepage":"https://github.com/shadcn-ui/cn#readme","bugs":{"url":"https://github.com/shadcn-ui/cn/issues"},"bin":{"cn":"bin/cn.mjs"},"dist":{"shasum":"3b92aa48431af76d122c0ae3cb3d9e53f862c51a","tarball":"https://registry.npmjs.org/cn/-/cn-0.2.2.tgz","fileCount":34,"integrity":"sha512-1TjHp2yGdFzu5Td2bc2bnceh/WKPEvLYVtcg6czWSifHBy5oN/bK5/I0eFNIr839Hlh5cxrV93Yh2ByrpO5Stw==","signatures":[{"sig":"MEUCIQDev2JkiHzEDpo8yk592NC7X03vEAT8LYFAaXOiZaQbXwIgYYg8UEZGRE73kLSNP+hdbUwTUmacRt8PfXcGItQ7oAI=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/cn@0.2.2","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":319472},"main":"./dist/index.cjs","type":"module","_from":"file:cn-0.2.2.tgz","types":"./dist/index.d.ts","module":"./dist/index.js","engines":{"node":">=20"},"exports":{".":{"import":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"require":{"types":"./dist/index.d.cts","default":"./dist/index.cjs"}},"./lite":{"import":{"types":"./dist/lite.d.ts","default":"./dist/lite.js"},"require":{"types":"./dist/lite.d.cts","default":"./dist/lite.cjs"}},"./config":{"import":{"types":"./dist/config.d.ts","default":"./dist/config.js"},"require":{"types":"./dist/config.d.cts","default":"./dist/config.cjs"}},"./engine":{"import":{"types":"./dist/engine.d.ts","default":"./dist/engine.js"},"require":{"types":"./dist/engine.d.cts","default":"./dist/engine.cjs"}},"./tables":{"import":{"types":"./dist/tables.d.ts","default":"./dist/tables.js"},"require":{"types":"./dist/tables.d.cts","default":"./dist/tables.cjs"}},"./compiler":{"import":{"types":"./dist/compiler.d.ts","default":"./dist/compiler.js"},"require":{"types":"./dist/compiler.d.cts","default":"./dist/compiler.cjs"}}},"scripts":{"build":"tsdown && node scripts/check-dts.mjs","compile-tables":"node scripts/compile-tables.mjs"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:189af90d-83b1-4f61-8b8e-0e7b7da7a8ff"}},"_resolved":"/tmp/fd16c4d6005acffef30d55b60aca9255/cn-0.2.2.tgz","_integrity":"sha512-1TjHp2yGdFzu5Td2bc2bnceh/WKPEvLYVtcg6czWSifHBy5oN/bK5/I0eFNIr839Hlh5cxrV93Yh2ByrpO5Stw==","repository":{"url":"git+https://github.com/shadcn-ui/cn.git","type":"git","directory":"packages/cn"},"_npmVersion":"11.19.1","description":"Fast, small, compiled class-name merging for Tailwind CSS. Drop-in replacement for clsx + tailwind-merge.","directories":{},"sideEffects":false,"_nodeVersion":"24.19.0","_hasShrinkwrap":false,"devDependencies":{"tsdown":"^0.12.0","typescript":"^5.7.0"},"_npmOperationalInternal":{"tmp":"tmp/cn_0.2.2_1788288642088_0.35070571627854163","host":"s3://npm-registry-packages-npm-production"}},"0.2.3":{"name":"cn","version":"0.2.3","keywords":["tailwind","tailwindcss","tailwind-merge","clsx","classnames","cn","class","merge"],"license":"MIT","_id":"cn@0.2.3","maintainers":[{"name":"shadcn","email":"m@shadcn.com"}],"homepage":"https://github.com/shadcn-ui/cn#readme","bugs":{"url":"https://github.com/shadcn-ui/cn/issues"},"bin":{"cn":"bin/cn.mjs"},"dist":{"shasum":"5ff1cb0f4041aa68dde16fcf2d691439ac9cccd7","tarball":"https://registry.npmjs.org/cn/-/cn-0.2.3.tgz","fileCount":34,"integrity":"sha512-z1S2v7FdtqcoXQzJWqNPBJ3KPG1or9FlefB0x+Eu8322BMmCSSVqzeI7itNj/6YRjyendnlWDJnKQkBhukT3fg==","signatures":[{"sig":"MEUCICVypfzo/vUDNmZZ+nGQBYgHg67q9lj+cqfL2RayXK0YAiEA22snR09zwR4dnY1X2e6D7ubhTynl7utHJsmtpKB8BG8=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/cn@0.2.3","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":325601},"main":"./dist/index.cjs","type":"module","_from":"file:cn-0.2.3.tgz","types":"./dist/index.d.ts","module":"./dist/index.js","engines":{"node":">=20"},"exports":{".":{"import":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"require":{"types":"./dist/index.d.cts","default":"./dist/index.cjs"}},"./lite":{"import":{"types":"./dist/lite.d.ts","default":"./dist/lite.js"},"require":{"types":"./dist/lite.d.cts","default":"./dist/lite.cjs"}},"./config":{"import":{"types":"./dist/config.d.ts","default":"./dist/config.js"},"require":{"types":"./dist/config.d.cts","default":"./dist/config.cjs"}},"./engine":{"import":{"types":"./dist/engine.d.ts","default":"./dist/engine.js"},"require":{"types":"./dist/engine.d.cts","default":"./dist/engine.cjs"}},"./tables":{"import":{"types":"./dist/tables.d.ts","default":"./dist/tables.js"},"require":{"types":"./dist/tables.d.cts","default":"./dist/tables.cjs"}},"./compiler":{"import":{"types":"./dist/compiler.d.ts","default":"./dist/compiler.js"},"require":{"types":"./dist/compiler.d.cts","default":"./dist/compiler.cjs"}}},"scripts":{"build":"tsdown && node scripts/check-dts.mjs","compile-tables":"node scripts/compile-tables.mjs"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:189af90d-83b1-4f61-8b8e-0e7b7da7a8ff"}},"_resolved":"/tmp/4313f26416e33204f54056eba79e65a5/cn-0.2.3.tgz","_integrity":"sha512-z1S2v7FdtqcoXQzJWqNPBJ3KPG1or9FlefB0x+Eu8322BMmCSSVqzeI7itNj/6YRjyendnlWDJnKQkBhukT3fg==","repository":{"url":"git+https://github.com/shadcn-ui/cn.git","type":"git","directory":"packages/cn"},"_npmVersion":"11.19.1","description":"Fast, small, compiled class-name merging for Tailwind CSS. Drop-in replacement for clsx + tailwind-merge.","directories":{},"sideEffects":false,"_nodeVersion":"24.19.0","_hasShrinkwrap":false,"devDependencies":{"tsdown":"^0.12.0","typescript":"^5.7.0"},"_npmOperationalInternal":{"tmp":"tmp/cn_0.2.3_1788311734714_0.6385774014677927","host":"s3://npm-registry-packages-npm-production"}},"0.2.4":{"name":"cn","version":"0.2.4","description":"Fast, small, compiled class-name merging for Tailwind CSS. Drop-in replacement for clsx + tailwind-merge.","license":"MIT","repository":{"type":"git","url":"git+https://github.com/shadcn-ui/cn.git","directory":"packages/cn"},"type":"module","sideEffects":false,"exports":{".":{"import":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"require":{"types":"./dist/index.d.cts","default":"./dist/index.cjs"}},"./engine":{"import":{"types":"./dist/engine.d.ts","default":"./dist/engine.js"},"require":{"types":"./dist/engine.d.cts","default":"./dist/engine.cjs"}},"./tables":{"import":{"types":"./dist/tables.d.ts","default":"./dist/tables.js"},"require":{"types":"./dist/tables.d.cts","default":"./dist/tables.cjs"}},"./config":{"import":{"types":"./dist/config.d.ts","default":"./dist/config.js"},"require":{"types":"./dist/config.d.cts","default":"./dist/config.cjs"}},"./compiler":{"import":{"types":"./dist/compiler.d.ts","default":"./dist/compiler.js"},"require":{"types":"./dist/compiler.d.cts","default":"./dist/compiler.cjs"}},"./lite":{"import":{"types":"./dist/lite.d.ts","default":"./dist/lite.js"},"require":{"types":"./dist/lite.d.cts","default":"./dist/lite.cjs"}}},"main":"./dist/index.cjs","module":"./dist/index.js","types":"./dist/index.d.ts","keywords":["tailwind","tailwindcss","tailwind-merge","clsx","classnames","cn","class","merge"],"devDependencies":{"tsdown":"^0.12.0","typescript":"^5.7.0"},"bin":{"cn":"bin/cn.mjs"},"engines":{"node":">=20"},"scripts":{"build":"tsdown && node scripts/check-dts.mjs","compile-tables":"node scripts/compile-tables.mjs"},"_id":"cn@0.2.4","bugs":{"url":"https://github.com/shadcn-ui/cn/issues"},"homepage":"https://github.com/shadcn-ui/cn#readme","_integrity":"sha512-SzQvoh5FwizWtQg9+JueKdjWhlfCZMdu5DqNHm9q1wUlRVmKb9WXlepR9bTTbPwzEOyX1ujJ6lcCppmn3bNUCg==","_resolved":"/tmp/7248873ee5467ed9aa9f259271c9cf80/cn-0.2.4.tgz","_from":"file:cn-0.2.4.tgz","_nodeVersion":"24.19.0","_npmVersion":"11.19.1","dist":{"integrity":"sha512-SzQvoh5FwizWtQg9+JueKdjWhlfCZMdu5DqNHm9q1wUlRVmKb9WXlepR9bTTbPwzEOyX1ujJ6lcCppmn3bNUCg==","shasum":"7965690707b2676d914cb8228efcfb134aa0090f","tarball":"https://registry.npmjs.org/cn/-/cn-0.2.4.tgz","fileCount":34,"unpackedSize":330511,"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/cn@0.2.4","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQDO8njLLzusb/Rex8rhVr5fMk7xD32mRuVCU8A7vMWdhgIhAPf1lnQ9J3nvxME2URJkGwAIpFiTW8yz4Cw/FrlqX4XE"}]},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:189af90d-83b1-4f61-8b8e-0e7b7da7a8ff"}},"directories":{},"maintainers":[{"name":"shadcn","email":"m@shadcn.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/cn_0.2.4_1788341196053_0.5050679880960318"},"_hasShrinkwrap":false}},"time":{"created":"2013-06-12T13:14:40.140Z","modified":"2026-09-02T09:26:36.646Z","0.1.0":"2013-06-12T13:14:43.114Z","0.1.1":"2013-06-12T15:24:22.450Z","0.2.0":"2026-09-01T12:17:43.869Z","0.2.1":"2026-09-01T16:43:00.700Z","0.2.2":"2026-09-01T18:50:42.216Z","0.2.3":"2026-09-02T01:15:34.861Z","0.2.4":"2026-09-02T09:26:36.212Z"},"bugs":{"url":"https://github.com/shadcn-ui/cn/issues"},"license":"MIT","homepage":"https://github.com/shadcn-ui/cn#readme","keywords":["tailwind","tailwindcss","tailwind-merge","clsx","classnames","cn","class","merge"],"repository":{"type":"git","url":"git+https://github.com/shadcn-ui/cn.git","directory":"packages/cn"},"description":"Fast, small, compiled class-name merging for Tailwind CSS. Drop-in replacement for clsx + tailwind-merge.","maintainers":[{"name":"shadcn","email":"m@shadcn.com"}],"readme":"# cn\n\n`cn` is a [new engine](https://github.com/shadcn-ui/cn/blob/main/docs/how-it-works.md) for Tailwind class merging and\nconflict resolution. It replaces `tailwind-merge` and `clsx`. Same APIs.\nFull parity. **And it is [30× faster](#how-much-faster).**\n\n```ts\nimport { cn } from \"cn\"\n\n// conditional joining (like clsx) + conflict resolution (like tailwind-merge)\ncn(\"px-2 py-1\", isActive && \"bg-blue-500\", { \"text-white\": isActive })\n```\n\n`cn` has zero dependencies and is framework-agnostic: it works with React,\nVue, Svelte, Solid, Astro, or plain server templates, and runs in browsers,\nNode, Bun, Deno, and edge runtimes.\n\n`cn` is built and maintained by [aidenybai](https://x.com/aidenybai) and [shadcn](https://x.com/shadcn).\n\n## Install\n\n```bash\nnpm i cn\n```\n\n### New project\n\nImport it and go. Nothing to configure:\n\n```tsx\nimport { cn } from \"cn\"\n\nexport function Button({\n  className,\n  active,\n  ...props\n}: React.ComponentProps<\"button\"> & { active?: boolean }) {\n  return (\n    <button\n      className={cn(\n        \"rounded-md px-4 py-2 text-sm\",\n        active && \"bg-primary\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n```\n\n### Existing shadcn/ui project\n\nYour components already import `cn` from `@/lib/utils`. Replace the wrapper with the one from `cn`.\n\n```diff\n// lib/utils.ts\n- import { clsx, type ClassValue } from \"clsx\";\n- import { twMerge } from \"tailwind-merge\";\n\n- export function cn(...inputs: ClassValue[]) {\n-   return twMerge(clsx(inputs));\n- }\n+ export { cn } from \"cn\";\n```\n\nThen remove `clsx` and `tailwind-merge` from your dependencies. If other\npackages still import them, [alias them to `cn`](https://github.com/shadcn-ui/cn/blob/main/docs/aliasing.md)\nso your bundle only carries one implementation.\n\n## How much faster?\n\nThe following benchmarks compare `cn` against `clsx` + `tailwind-merge`,\nwhich is what most projects run today.\n\nWe ran each library through every workload in its own isolated process with\nits own warmup, and kept the best of 5 runs.\n\nTo see the results for yourself, run `pnpm bench`. The methodology is\nin [docs/how-it-works.md](https://github.com/shadcn-ui/cn/blob/main/docs/how-it-works.md#benchmark-methodology).\n\n| scenario                                                   | clsx + tailwind-merge |     cn | faster² |\n| ---------------------------------------------------------- | --------------------: | -----: | ------: |\n| the call your components make most¹                        |                320 ns |  10 ns |     30× |\n| same classes as last render (cache hit)                    |                 14 ns |   7 ns |    1.9× |\n| typical component strings, warm                            |                 13 ns |   7 ns |    1.9× |\n| thousands of recurring strings (a real repo's working set) |                2.4 µs |  14 ns |    172× |\n| cold render, many arbitrary values                         |                3.4 µs | 1.1 µs |    3.0× |\n| cold render, SSR-style unique strings                      |                2.3 µs | 360 ns |    6.4× |\n| very first call (page load)                                |                3.2 ms | 0.4 ms |      7× |\n\n¹ `cn(base, variant, condition && extra)` with stable class strings. This is\nthe shape almost every component call has. `cn` learns repeated call\nsequences, so a render loop's calls verify by identity and skip the work\nentirely. The headline rounds down.\n\n² compared to `clsx` + `tailwind-merge`.\n\n### Real repositories\n\nThe rows above are synthetic. `pnpm bench:corpus` replays every `cn()` call\nharvested from 58 open source codebases (144,265 calls) through each\nlibrary, one isolated process per library and repository, and prints the\nper-repository table. Geometric mean across the 58 repositories: `cn` is\n**37× faster** than `clsx` + `tailwind-merge`.\n\n`cn` ships the least JavaScript to parse in every setup, 26 KB minified.\n\nIf you want an even smaller bundle with the same performance, see\n[`cn build`](https://github.com/shadcn-ui/cn/blob/main/docs/build-setup.md).\n\n## Custom themes\n\n`cn/config` accepts the same `{ extend, override, prefix }` shape, under the\nsame name:\n\n```ts\n// before\nimport { extendTailwindMerge } from \"tailwind-merge\"\n\nconst twMerge = extendTailwindMerge({\n  extend: { classGroups: { \"font-size\": [{ text: [\"hero\"] }] } },\n})\n```\n\n```ts\n// after\nimport { createCn } from \"cn/config\"\n\nconst cn = createCn({\n  extend: { classGroups: { \"font-size\": [{ text: [\"hero\"] }] } },\n})\n```\n\nCustom validator functions work as-is. `fromTheme`, `validators`,\n`mergeConfigs`, and `defaultConfig` are exported from `cn/config`. Tailwind\nv4 prefixes are supported: `createCn({ prefix: \"tw\" })`.\n\n## Coming from tailwind-merge\n\n`cn` produces the same output as tailwind-merge for every input. We verify\nthis with 356,000 differential tests.\n\nEvery export maps to the same name or a familiar one:\n\n| tailwind-merge               | cn                                     |\n| ---------------------------- | -------------------------------------- |\n| `twMerge(...)`               | `twMerge(...)` from `\"cn\"`, identical  |\n| `twJoin(...)`                | `twJoin(...)` from `\"cn\"`, identical   |\n| `extendTailwindMerge(ext)`   | same name, from `\"cn/config\"`          |\n| `createTailwindMerge(fn)`    | `createTwMerge(fn)` from `\"cn/config\"` |\n| `getDefaultConfig()`         | `defaultConfig()` from `\"cn/config\"`   |\n| `fromTheme`, `validators`    | same names, from `\"cn/config\"`         |\n| `mergeConfigs`               | same name, from `\"cn/config\"`          |\n| `experimentalParseClassName` | not supported                          |\n\n## Gotchas\n\n- `cn` supports Tailwind CSS v4, like tailwind-merge v3. On Tailwind v3,\n  stay with tailwind-merge v2.\n- Classes that merely _look like_ Tailwind utilities (`text-2xs`) are\n  treated as Tailwind utilities. Same behavior and guidance as\n  [tailwind-merge's docs](https://github.com/dcastil/tailwind-merge/blob/main/docs/limitations.md).\n- With [`cn build`](https://github.com/shadcn-ui/cn/blob/main/docs/build-setup.md), dynamically constructed class names (`\"p-\" + size`) can't\n  be detected. Same rule as Tailwind itself. Use `--safelist`.\n- The CLI needs Node 20+.\n\n## API\n\n- **`cn`**: `cn(...inputs)`, `twMerge(...)`, `twJoin(...)`, `clsx(...)`\n- **`cn/config`**: `createCn(ext?)`, `extendTailwindMerge(ext?)`,\n  `createTwMerge(ext?)`, `fromTheme`, `validators`, `defaultConfig()`,\n  `mergeConfigs(base, ext)`\n- **`cn/engine`**: `createCn(tables, ...)`, `createEngine(tables, ...)` for\n  build-time compiled tables\n- **`cn/lite`**: `clsx(...)`, strings-only join (`clsx/lite` parity)\n- **CLI**: `npx cn build --help`\n\n## Credits\n\n- `cn`'s merge engine, compiler, and table format are original work.\n- The package's conflict-resolution **semantics** intentionally match those of\n  [tailwind-merge](https://github.com/dcastil/tailwind-merge) by Dany Castillo\n  (MIT licensed), and the default tables it ships are compiled from\n  tailwind-merge's default configuration.\n- The `clsx`-compatible join layer implements the argument semantics of\n  [clsx](https://github.com/lukeed/clsx) by Luke Edwards (MIT licensed).\n- The argument-identity cache for repeated variadic calls re-implements an optimization pioneered by\n  [cnfast](https://github.com/aidenybai/cnfast) by Aiden Bai (MIT licensed).\n\nThank you to all three authors.\n","readmeFilename":"README.md","users":{"fgribreau":true}}