{"id":10636,"library":"classnames","title":"Conditional CSS Class Utility","description":"The `classnames` utility simplifies the conditional joining of CSS class names in JavaScript and TypeScript applications. It accepts any number of arguments, including strings, objects (where keys are class names and values are booleans), and arrays, intelligently combining them into a single, space-separated string. The package is currently at version 2.5.1, following the SemVer standard, indicating a strong commitment to stability and backwards compatibility for minor and patch releases. It is widely adopted, especially within the React ecosystem, due to its robust performance and minimalist API. Its key differentiators include its extreme stability, thorough test suite, and focus on performance, ensuring it reliably handles class name generation in high-frequency scenarios across browsers and Node.js environments. The project's philosophy emphasizes speed and stability, with updates thoroughly reviewed for performance implications.","status":"active","version":"2.5.1","language":"javascript","source_language":"en","source_url":"https://github.com/JedWatson/classnames","tags":["javascript","react","css","classes","classname","classnames","util","utility","typescript"],"install":[{"cmd":"npm install classnames","lang":"bash","label":"npm"},{"cmd":"yarn add classnames","lang":"bash","label":"yarn"},{"cmd":"pnpm add classnames","lang":"bash","label":"pnpm"}],"dependencies":[],"imports":[{"note":"The `classnames` function is a default export for ESM. Using named import `import { classNames } }` will result in a `TypeError`.","wrong":"import { classNames } from 'classnames';","symbol":"classNames","correct":"import classNames from 'classnames';"},{"note":"This is the correct CommonJS import. This pattern works in Node.js environments. As of v2.5.0, the package includes an 'exports' field for better ESM compatibility.","symbol":"classNames","correct":"const classNames = require('classnames');"},{"note":"For standalone browser usage, including `index.js` via a `<script>` tag exposes `classNames` as a global variable. This method is less common in modern module-driven frontends.","symbol":"classNames","correct":"if (window.classNames) { /* use window.classNames */ }"}],"quickstart":{"code":"import classNames from 'classnames';\n\nconst isActive = true;\nconst hasError = false;\nconst theme = 'dark';\n\n// Basic usage with strings\nconst classes1 = classNames('container', 'header');\nconsole.log(classes1); // Expected: 'container header'\n\n// Conditional classes using objects\nconst classes2 = classNames('button', {\n  'button--primary': isActive,\n  'button--danger': hasError,\n  [`theme-${theme}`]: true // Dynamic class name based on variable\n});\nconsole.log(classes2); // Expected: 'button button--primary theme-dark'\n\n// Mixing strings, objects, and arrays\nconst classes3 = classNames(\n  'card',\n  { 'card--active': isActive },\n  ['shadow', 'rounded'],\n  null,\n  undefined,\n  { 'card--hidden': !isActive }\n);\nconsole.log(classes3); // Expected: 'card card--active shadow rounded'","lang":"typescript","description":"Demonstrates various ways to combine class names, including static strings, conditional objects, arrays, and dynamic class names, handling falsy values gracefully."},"warnings":[{"fix":"For ESM, use `import classNames from 'classnames';`. For CommonJS, use `const classNames = require('classnames');`. Avoid `import { classNames } from 'classnames';` as it is a default export.","message":"Version 2.0.0 introduced ES6 module export. While existing CommonJS `require` statements continued to work, modern ESM `import` syntax changed how `classnames` should be imported. Incorrect import patterns (e.g., named imports for a default export) can lead to runtime errors.","severity":"breaking","affected_versions":">=2.0.0"},{"fix":"Upgrade to `classnames@2.5.0` or newer to leverage the `exports` field for more reliable module resolution. Ensure your bundler/Node.js version supports `package.json` `exports`.","message":"Prior to v2.5.0, module resolution for hybrid CJS/ESM projects, especially in Node.js environments with `\"type\": \"module\"` set, could be inconsistent. Version 2.5.0 added the `exports` field to `package.json` to improve module interoperability.","severity":"gotcha","affected_versions":"<2.5.0"},{"fix":"No direct fix needed, but be aware that older code relying on `component-classes` (if it was somehow exposed) would break. `classnames` itself does not expose this internally anymore.","message":"The `component-classes` dependency was removed in v2.0.0, streamlining the package. While not a direct breaking change for users, it signifies a move towards a leaner, dependency-free utility.","severity":"deprecated","affected_versions":">=2.0.0"},{"fix":"By default, `classnames` is optimized for speed. Only use the `dedupe` variant if you have a specific need for its deduplication behavior and have benchmarked its performance impact in your application. The core `classnames` function should be preferred for general use.","message":"There is an alternate `dedupe` version of `classNames` available that offers more robust deduplication for complex scenarios but is significantly slower (up to 10x slower). It is offered as an opt-in for specific use cases.","severity":"gotcha","affected_versions":">=2.1.0"}],"env_vars":null,"last_verified":"2026-04-19T00:00:00.000Z","next_check":"2026-07-18T00:00:00.000Z","problems":[{"fix":"Change your import statement to `import classNames from 'classnames';` for ES modules. If using CommonJS, ensure you are using `const classNames = require('classnames');`.","cause":"Attempting to use `classNames` after an incorrect ES module import (e.g., `import { classNames } from 'classnames';` instead of `import classNames from 'classnames';`). This happens because `classnames` exports a default function, not a named one.","error":"TypeError: classNames is not a function"},{"fix":"Prefer `import classNames from 'classnames';` in ES module contexts. If you *must* use `require` in an ESM file (e.g., for conditional loading), consider Node.js's `createRequire` utility: `import { createRequire } from 'module'; const require = createRequire(import.meta.url); const classNames = require('classnames');`.","cause":"In a Node.js project configured as an ES module (`\"type\": \"module\"` in `package.json`), trying to `require('classnames')` might fail if Node.js resolves `classnames` as an ES module due to its `exports` field. This is a common interoperability issue.","error":"ERR_REQUIRE_ESM (or similar module resolution errors in Node.js ESM projects)"},{"fix":"Review your bundler configuration and ensure proper handling of objects passed to `classnames`. If you encounter this, consider simplifying the arguments passed or upgrading your bundling tools. This issue was largely addressed in subsequent patch releases. Ensure `classnames` is at least v2.3.2.","cause":"This issue could arise in specific bundling scenarios (e.g., Rollup/Babel) when `classnames` introduced support for custom `toString()` methods on arguments in v2.3.0, potentially leading to objects not being stringified as expected.","error":"Class names being returned as `[object Object]` as of v2.3.0"}],"ecosystem":"npm"}