Monospace

cn

Tailwind CSS class merging utility combining clsx and tailwind-merge.

cn is a utility function that combines clsx and tailwind-merge for optimal Tailwind CSS class merging.

Import

import { cn } from '@repo/ui/utils/cn'

Signature

function cn(...inputs: ClassValue[]): string

Parameters

ParameterTypeDescription
...inputsClassValue[]Class names, arrays, objects, or conditional class values

Returns

A single string with merged and deduplicated class names.

Usage

import { cn } from '@repo/ui/utils/cn'

// Simple merging
cn('px-4 py-2', 'text-white')
// → "px-4 py-2 text-white"

// Conditional classes
cn('base-class', isActive && 'bg-blue-500', isDisabled && 'opacity-50')
// → "base-class bg-blue-500" (when isActive is true, isDisabled is false)

// Tailwind conflict resolution
cn('px-4', 'px-6')
// → "px-6" (tailwind-merge resolves the conflict)

// Object syntax
cn('text-white', { 'bg-red-500': hasError, 'bg-green-500': !hasError })

How It Works

  1. clsx processes the input — handles conditional classes, arrays, and objects
  2. tailwind-merge resolves conflicting Tailwind classes — later values override earlier ones

This prevents common issues where Tailwind classes conflict:

// Without cn: both px-2 and px-4 are in the output (undefined behavior)
<div className={`px-2 ${large ? 'px-4' : ''}`} />

// With cn: px-4 correctly overrides px-2
<div className={cn('px-2', large && 'px-4')} />

Source

packages/ui/src/utils/cn.ts
import { type ClassValue, clsx } from 'clsx'
import { twMerge } from 'tailwind-merge'

export const cn = (...inputs: ClassValue[]): string => {
  return twMerge(clsx(inputs))
}

On this page