Skip to content

Bug Report: twMerge not properly merging conflicting classes from base and class prop since v2.1.0 #258

@Yasso9

Description

@Yasso9

Describe the bug
When using twMerge: true with tailwind-variants, conflicting Tailwind classes from the base configuration and the class prop are not being properly merged. Instead of the class prop overriding conflicting base classes, both classes are included in the output.

To Reproduce
Steps to reproduce the behavior:

  1. Create a tailwind-variants instance with twMerge: true (even though by default it is true)
  2. Define a variant with base classes containing a specific utility (e.g., justify-center)
  3. Call the variant function with a conflicting class in the class prop (e.g., justify-between)
  4. Observe that both classes are output instead of the conflicting class being resolved
import { createTV } from 'tailwind-variants'

const tv = createTV({
    twMerge: true,
})

const variant = tv(
    {
        base: ['justify-center'],
    },
    { twMerge: true },
)

console.log(variant({ class: 'justify-between' }))
// Expected: "justify-between"
// Actual: "justify-center justify-between"

In a more minimal example, this can be reproduced as follows:

import { tv } from 'tailwind-variants'

const variant = tv({
    base: ['justify-center'],
})

console.log(variant({ class: 'justify-between' }))
// Expected: "justify-between"
// Actual: "justify-center justify-between"

Expected behavior
When conflicting Tailwind classes are provided, twMerge should resolve the conflict by keeping only the class from the class prop, similar to how tailwind-merge works directly. The output should be "justify-between" instead of "justify-center justify-between".

Screenshots
N/A - This is a programmatic issue with class merging.

Desktop (please complete the following information):

  • OS: Linux
  • Browser: Firefox 141.0 and Chromium 138.0
  • Version: N/A

Smartphone (please complete the following information):
N/A - This affects all environments where tailwind-variants is used.

Additional context
This issue was observed in a project using tailwind-variants version 2.1.0 and tailwind-merge version 3.3.1. Pinning tailwind-variants to version 2.0.1 resolves the issue, indicating a regression in the 2.1.0 release.

Also for comparison, using tailwind-merge directly works as expected:

import { twMerge } from 'tailwind-merge'

console.log(twMerge('justify-center', 'justify-between'))
// Output: "justify-between" ✅

The issue appears to be that tailwind-variants is not properly applying twMerge.

I also correctly have tailwind-merge installed.
Output of npm list tailwind-merge:

├── [email protected]
└─┬ [email protected]
  └── [email protected] deduped

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions