frontend

React ClassNames Aggregator

January 24, 2026

React ClassNames Aggregator

Overview

The classNames utility is a popular helper function for conditionally joining classNames together. It's commonly used in React applications to dynamically construct className strings based on conditions, making it easier to apply conditional styling.

Basic Implementation

// Create a classNames util/polyfill method
/**
 * @param {...(any|Object|Array<any|Object|Array>)} args
 * @return {string}
 */
export default function classNames(...args) {
  const classes = [];

  const process = (arg) => {
    if (!arg) return;
    if (typeof arg === "string" || typeof arg === "number") {
      classes.push(arg);
    } else if (Array.isArray(arg)) {
      arg.forEach(process); // Recurse into arrays
    } else if (typeof arg === "object") {
      for (let key in arg) {
        if (Object.hasOwn(arg, key) && arg[key]) {
          classes.push(key);
        }
      }
    }
  };

  args.forEach(process);

  return classes.join(" ");
}

Usage Examples

Basic Usage

classNames('foo', 'bar'); // 'foo bar'
classNames('foo', { bar: true }); // 'foo bar'
classNames({ 'foo-bar': true }); // 'foo-bar'
classNames({ 'foo-bar': false }); // ''
classNames({ foo: true }, { bar: true }); // 'foo bar'
classNames({ foo: true, bar: false }); // 'foo'

Conditional Classes

classNames('foo', { bar: isBar }, { baz: isBaz });

Arrays

classNames(['foo', 'bar']); // 'foo bar'
classNames(['foo', { bar: true }]); // 'foo bar'

React Example

function Button({ primary, disabled, className, children }) {
  return (
    <button
      className={classNames(
        'btn',
        {
          'btn-primary': primary,
          'btn-disabled': disabled
        },
        className
      )}
    >
      {children}
    </button>
  );
}

Best Practices

  1. Use for Conditional Classes: Perfect for conditional styling
  2. Keep It Simple: Don't overcomplicate logic
  3. Performance: Efficient for most use cases
  4. Type Safety: Consider TypeScript for type safety