Skip to content

francoismassart/eslint-plugin-tailwindcss

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

449 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

eslint-plugin-tailwindcss
npm latest version license downloads

eslint-plugin-tailwindcss

This project needs your help

Support eslint-plugin-tailwindcss

I spent countless days working on this plugin, and it is available to everyone for free.
If you benefit from my work and if you want to help me keep the project alive, consider becoming a sponsor.

Premium sponsors Current sponsors
Sent.dm @codecov @getsentry

GitHub Sponsors | thanks.dev Sponsors

Rules

💼 Configurations enabled in.
⚠️ Configurations set to warn in.
✅ Set in the recommended configuration.
🔧 Automatically fixable by the --fix CLI option.
💡 Manually fixable by editor suggestions.

Name                               Description 💼 ⚠️ 🔧 💡
classnames-order Enforces a consistent order for the Tailwind CSS classnames, based on the compiler. 🔧
enforces-negative-arbitrary-values Warns about - prefixed classnames using arbitrary values. 🔧
enforces-shorthand Avoid using multiple Tailwind CSS classnames when not required. 🔧
important-modifier-suffix In v4 you should place the ! at the very end of the class name. 🔧
no-arbitrary-value Forbid using arbitrary values in classnames.
no-contradicting-classname Avoid contradicting Tailwind CSS classnames. 💡
no-custom-classname Detects classnames which do not belong to Tailwind CSS. 💡
no-unnecessary-arbitrary-value Avoid unjustified arbitrary classnames. 🔧 💡

Getting started

1. Install the plugin

npm i -D eslint-plugin-tailwindcss

  • As it is a dev dependency, it will not affect your final bundle size 🪶
  • It can be installed with other package managers such as pnpm
  • We support ESLint v10

If you are still using Tailwind CSS v3 and/or older ESLint versions, you can use eslint-plugin-tailwindcss@3.x.x

2. Edit your eslint.config file

Here is a very basic example:

// 1. import the plugin
import eslintPluginTailwindcss from "eslint-plugin-tailwindcss";
import { defineConfig } from "eslint/config";

export default defineConfig([
  {
    // 2. Optional: extend an existing config preset
    extends: [eslintPluginTailwindcss.configs.recommended],
    settings: {
      // 3. Define the tailwindcss settings with the MANDATORY cssConfigPath
      tailwindcss: {
        cssConfigPath: "./src/styles/tailwind.css",
      },
    },
    // 4. Optional: customize the rules to your needs
    rules: {
      "tailwindcss/classnames-order": "warn",
      "tailwindcss/no-arbitrary-value": "warn",
      "tailwindcss/no-custom-classname": [
        "warn",
        { whitelist: ["custom\\-*"] },
      ],
      "tailwindcss/no-contradicting-classname": "warn",
    },
  },
]);

cssConfigPath can be an absolute or a relative path. If you provide a relative path, the plugin will attempt to convert it into an absolute path.

Typesafe settings 🤓

The plugin also exports the type PluginSettings which you can use to benefit from autocomplete and validation directly inside your eslint.config file.

  1. You may need to add // @ts-check to force type checking
  2. Add the magic JSDoc comment /** @type {import('eslint-plugin-tailwindcss').PluginSettings} */

Here is a snippet, notice the object is surrounded by parentheses ({...}):

settings: {
  tailwindcss:
    /** @type {import('eslint-plugin-tailwindcss').PluginSettings} */
    ({
      cssConfigPath: './styles/tailwind.css',
    }),
},

3. Going further

You can also:

  • Run the linting process inside a pipeline of your hosted repository. I recommend running it on your merge/pull requests, rather than on every single (pre-)commit.
  • Auto-format on save in your favorite IDE.

Settings

Most of the rules solely use the shared settings (shared across all the plugin rules). Learn about eslint shared settings from the official documentation.

Here is a fully detailed example of shared settings:

// eslint.config.mjs
{
  settings: {
    tailwindcss: {
      // Attributes/props that could contain Tailwind CSS classes...
      // Optional, default values: ["class", "className", "ngClass", "@apply"]
      attributes: ["class"],
      // The (absolute or relative) path pointing to you main Tailwind CSS v4 config file.
      // It must be a `.css` file (v4), not a `.js` file (v3)
      // REQUIRED, as the default value may not work out-of-the-box
      cssConfigPath: "./styles/tailwind.css",
      // Functions/tagFunctions that will be parsed by the plugin.
      // Optional, default values: ["classnames", "classNames", "clsx", "cn", "ctl", "cva", "tv", "tw", "twMerge", "twJoin"]
      functions: ["twClasses"],
      // Within the list of functions, which should we check the keys instead of the values (used for `clsx`, etc.)
      // Optional, default values: ["classnames", "classNames", "clsx"]
      parseKeyFunctions: ["clsx"],
      // Keys to be ignored in object expressions
      // Optional, default values: ["defaultVariants", "compoundVariants", "compoundSlots"]
      ignoredKeys: ["defaultVariants", "compoundVariants", "compoundSlots", "specificKey"],
      // Max size of the Set or Map objects used for caching
      // Optional, default value: 250_000
      cacheMaxSize: 150_000,
      // Max lifetime of the cache set in ms
      // Optional, default value: 10 * 60 * 1000 (10 minutes)
      cacheMaxAge: 60 * 1000,
    },
  }
}

The default settings are exported via the DEFAULT_SETTINGS.

Contributing

The project is open to all developers, you can contribute to eslint-plugin-tailwindcss.

However, make sure to discuss the issue or the feature you wish to implement prior to getting to work unless you feel adventurous.

About

ESLint plugin for Tailwind CSS usage

Topics

Resources

License

Code of conduct

Contributing

Stars

2.1k stars

Watchers

12 watching

Forks

Sponsor this project

 

Packages

 
 
 

Contributors