# Custom merging

> Resolve conflicting Tailwind classes with a custom composer.

By default, `cn('px-2', 'px-4')` keeps both classes. To make the later Tailwind utility replace the earlier one, configure `tailwind-merge` as the composer.

## Configure Tailwind-aware merging

Install `tailwind-merge` in the same application package. Put the configuration in the shared style module so every component gets the same behavior.

### Install with bun

```sh
bun add @hulla/style tailwind-merge
```

### Install with npm

```sh
npm install @hulla/style tailwind-merge
```

### Install with pnpm

```sh
pnpm add @hulla/style tailwind-merge
```

### Install with yarn

```sh
yarn add @hulla/style tailwind-merge
```

```ts filename="src/lib/style.ts"
import { style } from '@hulla/style'
import { twMerge } from 'tailwind-merge'

export const { cn, vn } = style({ composer: twMerge })
```

Now `cn('rounded px-2', 'px-4')` returns `rounded px-4`. The same composer is used for both `cn` calls and classes returned by `vn`, so the output of a variant participates when you compose it with other classes.

## Choose the right boundary

Only the composer changes in this setup; `@hulla/style` still serializes objects and arrays before passing strings to it. `tailwind-merge` is an optional dependency that applies its own Tailwind conflict rules. It does not generate styles, and the default configuration of `@hulla/style` does not perform Tailwind-aware merging.

You can also provide your own `composer` or `serializer` through `style({ composer, serializer })`. A custom composer receives serialized strings in argument order. A custom serializer receives every input, including strings, so use it only when you need to change how inputs are converted. See [Composition](https://hulla.dev/docs/style/composition.md) for class inputs and [Variants](https://hulla.dev/docs/style/variants.md) for how variant output enters the same composition path.
