eslint-plugin-css-modules-next weekly downloads statistics
By stevegcarpenter · npm · ESLint plugins
ESLint plugin for CSS modules validation — catches undefined and unused CSS classes
eslint-plugin-css-modules-next has 1,438 recorded weekly downloads on npm.
About eslint-plugin-css-modules-next
eslint-plugin-css-modules-next
ESLint plugin for CSS Modules validation. Catches undefined and unused CSS classes, enforces co-location conventions, and disallows dynamic class access patterns that cannot be statically verified.
Supports .css, .scss, and .less module files.
Motivation
This plugin is inspired by eslint-plugin-css-modules. That project is no longer maintained and has a number of unresolved issues. eslint-plugin-css-modules-next aims to provide the same core functionality while fixing many of the issues that existed with the original plugin.
Capabilities
ESLint v9 and v10 Uses flat config format and is fully compatible with ESLint v9 and v10.
Pseudo-class selectors
Classes referenced inside :not(), :where(), :is(), and :has() are correctly treated as local class names. A pattern like .root { &:not(.selected) { } } makes .selected a valid defined class — styles.selected will not produce a false positive. Classes inside :global() are correctly excluded since they belong to the global scope.
Nested classes
Classes defined in nested rules are each tracked as independent local class names, whether the nesting is CSS-native (.card { .header { } }) or a compound selector (.card .header { }). Both produce card and header as defined classes. SCSS and LESS nesting are handled equivalently.
import * as styles syntax
import * as styles from './Foo.module.css' works identically to import styles from './Foo.module.css'. All rules apply equally to both forms.
@keyframes blocks
Animation names in @keyframes are never treated as CSS class names. A stylesheet that defines @keyframes spin { } and uses animation: spin 1s infinite will not report spin as a defined or unused class.
:global and :local scoping
All three forms of :global are correctly handled: the function form (:global(.Foo)), the space form (:global .Foo { }), and the block form (:global { .Foo { } }) each exclude their nested classes from the module's local export set. Within a :global { } block, :local(.foo) re-enables local scope and the class is included as an export.
@value declarations
Named values exported via @value name: value; are included as valid module exports. styles.name backed by a @value declaration is treated the same as a class name — the plugin validates both.
:export blocks
Properties declared inside :export { } (the ICSS mechanism for publishing arbitrary values from a CSS module) are included as valid exports. styles.myProp backed by :export { myProp: something; } is treated the same as a class name.
Attribute selectors
Class-like strings that appear as attribute selector values — for example a[href=".notAClass"] — are stripped before parsing so they never produce phantom class names.
Installation
npm install --save-dev eslint-plugin-css-modules-next
# or
pnpm add -D eslint-plugin-css-modules-next
# or
yarn add --dev eslint-plugin-css-modules-next
Usage
Recommended config (flat config)
// eslint.config.js
import cssModules from 'eslint-plugin-css-modules-next';
export default [
cssModules.configs.recommended,
];
The recommended config enables all four rules with the following severity:
| Rule | Severity |
|---|---|
css-modules-next/invalid-css-module-filepath | error |
css-modules-next/no-dynamic-class-access | error |
css-modules-next/no-undefined-class | error |
css-modules-next/no-unused-class | error |
Manual config
// eslint.config.js
import cssModules from 'eslint-plugin-css-modules-next';
export default [
{
plugins: { 'css-modules-next': cssModules },
rules: {
'css-modules-next/invalid-css-module-filepath': 'error',
'css-modules-next/no-dynamic-class-access': 'error',
'css-modules-next/no-undefined-class': 'error',
'css-modules-next/no-unused-class': 'error',
},
},
];
Settings
The shared settings['css-modules-next'] block is plugin-wide configuration consumed by every rule. It currently holds three keys: localsConvention, cacheSize, and relativePaths.
localsConvention (shared)
Type: "asIs" | "camelCase" | "camelCaseOnly"
Default: "asIs"
localsConvention describes how your CSS modules bundler exports kebab-case class names to JavaScript, and it needs to be consistent across both rules. Rather than repeating it in each rule's options (where the two copies can silently drift), set it once in shared settings as a single source of truth:
// eslint.config.js
export default [
{
settings: {
'css-modules-next': { localsConvention: 'camelCase' },
},
rules: {
'css-modules-next/no-undefined-class': 'error',
'css-modules-next/no-unused-class': 'error',
},
},
];
Precedence is: a rule's own localsConvention option (if set) wins; otherwise the shared settings value applies; otherwise the "asIs" default. So shared settings apply to every rule, while any single rule can still override the convention for itself. See each rule's localsConvention option for the meaning of each value.
cacheSize (shared)…
Description from the npm listing.
- eslint
- eslint-plugin
- css-modules
- css
- scss
- less
README badge
Show your rank in a README or on your website. The badge updates automatically.
Charts
Images: 30d · 1y · all time · 1600×900 dark
Adoption over time
7/30/90-day growth
Ranking history
Listing placement
Listing placement
Filled points are observed values; hollow points come from Internet Archive snapshots of the listing page. Dashed segments span periods with no observations — values between points are not interpolated.
Each band is one page of 20. Weekly downloads on a linear scale. Placement is projected from weekly downloads, so it can differ from the marketplace's own sort order. Hover a dot to see the listing.
Recent observations
Full history (1)Similar npm ESLint plugins plugins
All 20 eslint-plugin-css-modules-next alternativesData source
Weekly downloads (trailing 7 complete days) come from the official npm downloads API. Downloads include CI and mirrors and are not equivalent to installs or users. npm publishes no ratings.
Listing: https://www.npmjs.com/package/eslint-plugin-css-modules-next. First seen Oct 27, 2026; last successful collection Oct 27, 2026. See the methodology.