Create and format BEM class names for React components.

Usage no npm install needed!

<script type="module">
  import wavevisionClassName from 'https://cdn.skypack.dev/@wavevision/class-name';


Wavevision s.r.o.

Class Name

CI Coverage Status npm

Create and format BEM class names for React components. The formatter uses simplified BEM syntax.


Via Yarn

yarn add @wavevision/class-name

or npm

npm install --save @wavevision/class-name


Simple React component

import React, { useState, FunctionComponent } from 'react';
import className, { USE_VALUE } from '@wavevision/class-name';

interface ComponentProps {
  align: string;
  booleanProp: boolean;
  nullableProp: string | null;
  stringProp: string;

interface ComponentState {
  visible: boolean;

// Define base class name with props and state behaving as modifiers
const componentClassName = className<ComponentProps, ComponentState>(
  () => ({
    // if booleanProp value is truthy, 'booleanProp' will be used as modifier
    booleanProp: true,
    // if stringProp value is truthy then the value will be used
    stringProp: USE_VALUE,
    // use callback for custom modifiers, string returned will be used
    customModifier: ({ props }) => (props.nullableProp ? 'custom' : null),
    // if a non-string truthy value is returned, key will be used
    anotherModifier: ({ state }) => state.visible,

// We can also have modifiers defined only if some condition is met
const anotherClassName = className<ComponentProps, ComponentState>(
  ({ props, state }) => {
    if (props.nullableProp !== null) {
      // the whole set of modifiers will be created only if nullableProp is not null
      return { stringProps: USE_VALUE, customModifier: () => true };
    if (state.visible) {
      // this set will be created only if state.visible is true
      return { customModifier: () => true };

const Component: FunctionComponent<ComponentProps> = props => {
  const [visible] = useState<ComponentState['visible']>(false);
  const className = componentClassName({ props, state: { visible } });
  const nextClassName = anotherClassName({ props, state: { visible } });
  return (
    <div className={className.block('inline-modifier')}>
      <div className={nextClassName.block()} />
          // extra class name with optional prefix (e.g. Bootstrap text utility)
          className.extra(props.align, 'text'),
      // modifiers can be nullable and will be used only if not null
      <div className={className.element('element', props.nullableProp)} />
      <div className={className.element('another', 'element-modifier')} />

will output following when rendered

  class="component-class component-class--boolean-prop component-class--something component-class--inline-modifier"
  <div class="another-class"></div>
  <div class="component-class__child text-right"></div>
  <div class="component-class__element"></div>
    class="component-class__another component-class__another--element-modifier"