Hexi

Hexi

Record my life

Introduction to eslint-plugin-classname-arg-last

Prerequisite Knowledge#

When using Tailwind CSS, combining class names is a common requirement. We often use a method called cn to efficiently and elegantly manage classes, which typically encapsulates the following two commonly used tools:

1. clsx#

  • A lighter and more performant alternative to classnames.
  • Supports combining classes in the form of strings, objects, arrays, etc.
  • Example:
    clsx('btn', { 'btn-primary': isPrimary }) // => 'btn btn-primary'
    

2. tailwind-merge (abbreviated as twMerge)#

  • Used to merge conflicting Tailwind CSS class names.
  • Handles conflicts like text-sm text-lg, retaining the last class with higher priority.
  • Example:
    twMerge('text-sm text-lg') // => 'text-lg'
    

3. cn Method Encapsulation#

Combining the above two libraries into a unified cn method:

import { clsx, type ClassValue } from 'clsx'
import { twMerge } from 'tailwind-merge'

export function cn(...inputs: ClassValue[]) {
  return twMerge(clsx(...inputs))
}

4. Why should className be the last parameter?#

To ensure that user-provided styles can override default styles, it is recommended to place className last:

cn('default-class', className)

Because twMerge merges from left to right, the later classes will take precedence. If the order is reversed, the component's default styles may override user intentions.


What Did I Do?#

To maintain consistency in the practice of placing className at the end of the parameters, I developed an ESLint plugin for static detection and automatic fixing with the help of Grok3, compatible with Eslint v7-v9.

Source:#

eslint-plugin-classname-arg-last

Example:#

// Error example
cn(className, 'text-sm')

// Correct usage
cn('text-sm', className)

Configuration:#

Add to .eslintrc.js:

module.exports = {
  // ...
  plugins: ['classname-arg-last'],
  rules: {
    'classname-arg-last/classname-arg-last': 'error',
  },
}

With this plugin, you can standardize practices during the development phase and reduce style conflicts caused by order issues.

Loading...
Ownership of this post data is guaranteed by blockchain and smart contracts to the creator alone.