You’ll often see cn, clsx, and twMerge in Tailwind projects, especially if you’re using shadcn/ui.

But what are they, and why do we use them?

These utilities help manage Tailwind classes in a clean, scalable way. Instead of messy string concatenation, they handle conditional logic, remove duplicates, and resolve conflicts automatically.

Let’s take an example to understand why and how they’re used.

Suppose you are creating a Card component that accepts children and renders with some default styling. But it’s not always the case that you only want the default styles sometimes you need to provide your own Tailwind utility classes.

The common approach is to accept a className prop and pass it down to the Card.

However, since Tailwind utilities are just strings, you might be tempted to concatenate them like this:

<div className={"backdrop-blur-md " + className}>{children}</div>

But this is not a feasible solution. Why?

The solution is to use clsx.


import { clsx } from "clsx";

function Card({ children, className }: { children: React.ReactNode; className?: string }) {
  return (
    <div className={clsx("backdrop-blur-md", className)}>
      {children}
    </div>
  );
}

Problem with clsx