DEV Community

Cover image for “cn” utility function in shadcn-ui/ui:
Ramu Narasinga
Ramu Narasinga

Posted on

“cn” utility function in shadcn-ui/ui:

When I saw the cn function being imported from @/lib/utils in shadcn-ui/ui source code, I assumed that this function’s name is derived from “shadcn” since it contains “cn’’and that it handles some core logic but turns out, it is a wrapper on top of clsx and twMerge. I questioned, Why? Why would you need such a wrapper?

To understand the reason behind this cn wrapper, you must first understand clsx and tailwind-merge.


Clsx official docs definition is that it is a tiny (239B) utility for constructing className strings conditionally.

Also serves as a faster & smaller drop-in replacement for the classnames module.

Build shadcn-ui/ui from scratch.

### Examples:

import clsx from 'clsx';
// or
import { clsx } from 'clsx';

// Strings (variadic)
clsx('foo', true && 'bar', 'baz');
//=> 'foo bar baz'

// Objects
clsx({ foo:true, bar:false, baz:isTrue() });
//=> 'foo baz'

// Objects (variadic)
clsx({ foo:true }, { bar:false }, null, { '--foobar':'hello' });
Enter fullscreen mode Exit fullscreen mode

We all are familiar with the clsx package, it is used to render the classnames conditionally.


To be honest, I have never used the tailwind-merge package before. So I visited the official docs and learnt that it is a utility function to efficiently merge Tailwind CSS classes in JS without style conflicts.


import { twMerge } from 'tailwind-merge'

twMerge('px-2 py-1 bg-red hover:bg-dark-red', 'p-3 bg-\[#B91C1C\]')
// → 'hover:bg-dark-red p-3 bg-\[#B91C1C\]'
Enter fullscreen mode Exit fullscreen mode

Connecting the dots:

It was at this point, it occurred to me that in shadcn-ui, clsx conditionally renders tailwind class names as strings and doing so could result in tailwind class name conflicts

Cn usage in shadcn-ui/ui:

I found the following files using cn function



Top comments (0)