This is an ESLint plugin to check that CSS classes used in JS/TS files exist in your stylesheets. It's loosely inspired by the no-custom-classname
rule from https://github.com/francoismassart/eslint-plugin-tailwindcss, but minus the Tailwind aspects.
npm install eslint-plugin-css-class-usage
Add the plugin to your ESLint configuration. If you're using the new flat config (eslint.config.js):
import cssClassUsagePlugin from 'eslint-plugin-css-class-usage';
export default [
{
plugins: {
'css-class-usage': cssClassUsagePlugin
},
rules: {
'css-class-usage/no-unknown-classes': 'error'
}
}
];
Or if you're using the traditional configuration (.eslintrc.js):
module.exports = {
plugins: ['css-class-usage'],
rules: {
'css-class-usage/no-unknown-classes': 'error'
}
};
The plugin supports the following configuration options:
{
'css-class-usage/no-unknown-classes': ['error', {
// Attributes to check in JSX elements (default: ['className', 'class', 'classList'])
classAttributes: ['className', 'class', 'classList'],
// Function names that handle class composition (default: ['clsx', 'classNames', 'cx'])
classFunctions: ['clsx', 'classNames', 'cx'],
// Glob patterns for your CSS files (default: ['**/*.css'])
cssFiles: ['**/*.css'],
// Glob patterns for files to ignore (default: ['**/node_modules/**', '**/dist/**', '**/out/**', '**/build/**'])
ignore: ['**/node_modules/**', '**/dist/**', '**/out/**', '**/build/**']
// Whether to enable the file watcher for changes to CSS files. This is
// useful when used as part of an editor plugin but can cause CI jobs
// to hang. By default, the watcher is enabled only if the running script
// has `serve` or `watch` in its name (the VSCode ESLint extension is
// named `eslintServer`). This behavior can be overridden by running
// your own check and setting this option to true or false accordingly.
watch: 'auto'
}]
}
All configuration options are optional and will use their default values if not specified.
This rule ensures that any CSS classes referenced in your JavaScript/TypeScript code actually exist in your CSS files. It helps catch typos and maintains consistency between your code and styles.
// ❌ Error: Class 'non-existent-class' does not exist in CSS files
const element = <div className="non-existent-class">Content</div>;
// ✅ Valid: Class exists in CSS files
const element = <div className="existing-class">Content</div>;
// ✅ Valid: Multiple classes that exist
const element = <div className="header main-content">Content</div>;
// ❌ Error: One of the classes doesn't exist
const element = <div className="header non-existent">Content</div>;
The rule supports:
- String literals in JSX attributes (e.g.,
className="my-class"
) - Multiple classes in a single string (e.g.,
className="header main-content"
) - Object syntax in JSX (e.g.,
className={{ active: true }}
) - Class utility functions (e.g.,
clsx('foo', { bar: true })
) - Tailwind modifiers (e.g.,
hover:bg-blue-500
) - modifiers are automatically stripped when checking - Tailwind arbitrary values (e.g.,
[mask-type:luminance]
) - these are automatically ignored
Pull requests are welcome! Please make sure to update tests as appropriate.