Library / SDK
dukeluo/eslint-plugin-check-file avatar
dukeluo/eslint-plugin-check-file

eslint-plugin-check-file: enforcing filename and folder naming with ESLint

ESLint rules for consistent filename and folder. Allows you to enforce a consistent naming pattern for the filename and folder.

616 stars26 forksJavaScriptApache-2.0

At a glance

What is it?
eslint-plugin-check-file is an ESLint plugin with five rules that check file and directory names against glob patterns and naming conventions, including a rule that forbids files named index. Version 3 and above require flat configuration.
Who is it for?
Adopt eslint-plugin-check-file when your repository has an agreed naming convention that lint rules never touched, especially when index files and scattered test files are the problem, and skip it if your naming policy is enforced by a separate CI script you already maintain.
Can I use it commercially?
Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 40 days ago.
What is it written in?
Mainly JavaScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.

Editorial analysis

What the plugin checks that no core ESLint rule can

ESLint looks inside files. It parses JavaScript and TypeScript and reports on the code. It has no opinion about what the file is called or which directory it sits in, because those are properties of the filesystem rather than of the source text.

That gap is where eslint-plugin-check-file works. It is described as an ESLint plugin that enforces consistent naming conventions for files and folders in your project, and it does so by letting you define specific patterns for filenames and directory structures. The description in the repository metadata puts it as ESLint rules for consistent filename and folder, allowing you to enforce a consistent naming pattern for the filename and folder.

The five rules cover the range of naming problems a team actually accumulates. check-file/no-index forbids a file from being named index, which is the single most useful one in a codebase built on barrel files. check-file/filename-blocklist blocks filenames by pattern. check-file/folder-match-with-fex enforces a consistent naming pattern for folder names for specified files, meaning you can require that anything matching a given file glob lives in a given directory. check-file/filename-naming-convention and check-file/folder-naming-convention enforce patterns for specified files and specified folders respectively.

So this is not a general purpose file linter. It is a way to encode a naming policy you already have in your head into a file that runs in CI.

Patterns are glob keys mapped to conventions

The configuration model is consistent across all five rules and it is worth understanding precisely, because the examples in the README are dense but the shape is simple.

Each rule takes an object. The keys are glob patterns that select which files or folders the rule applies to, and the values are the expectation. In the naming convention rules the value is a convention name such as PASCAL_CASE or CAMEL_CASE. In the blocklist rule the value is a replacement name, so a pattern matching a .model.ts file mapped to *.models.ts flags every file that should be called .models.ts instead. In the folder match rule the value is a directory glob, so a file glob of *.test.{js,jsx,ts,tsx} mapped to a __tests__ directory glob means any test file outside a __tests__ directory is an error.

Because the mapping is glob to glob rather than glob to a literal, the rules compose with the same glob syntax ESLint already uses in its files patterns, including brace expansion like {js,jsx,ts,tsx} and extglob patterns. The folder naming example shows why that matters, with a rule that applies PASCAL_CASE to the direct children of src/components and CAMEL_CASE to everything under src except those component directories and the __tests__ directories, so the component folder is treated differently from the rest of the tree.

This design has a cost. Because a convention is expressed as a name rather than as a regular expression, the set of conventions you can express is fixed by the plugin. If your team needs kebab-case with a numeric suffix rule, or a two-segment name convention, you should check the rule documentation under docs/rules/ before committing to it.

Installation is two npm commands

The plugin needs ESLint itself, which most projects already have, and the package is published to npm.

sh
npm i eslint --save-dev
sh
npm install eslint-plugin-check-file --save-dev

Both are saved as dev dependencies, which is right, since these rules are a development-time concern and have no place in a production install.

One configuration detail matters more than the install. The plugin supports ESLint's flat configuration, and the README includes a processor entry in the same config array:

javascript
  {
    // optional: add this processor to files which not processed by other processors but still require linting
    files: ['**/*.yaml', '**/*.webp'],
    processor: 'check-file/eslint-processor-check-file',
  },

That processor is what lets the plugin run on files that ESLint would otherwise not process at all. YAML and webp are not JavaScript, so ESLint ignores them by default, and the processor gives the plugin a way to see them so it can check their names. The comment marks it optional, and it is the piece most people skip, which is the piece that makes the difference between checking only source files and checking the whole tree.

The full rule set in one config array

The README's complete example is worth reading closely, because it shows how the rules sit side by side and where the files pattern scopes them.

javascript
    files: ['src/**/*.*'],
    plugins: {
      'check-file': checkFile,
    },
    rules: {
      'check-file/no-index': 'error',
      'check-file/filename-blocklist': [
        'error',
        {
          '**/*.model.ts': '*.models.ts',
          '**/*.util.ts': '*.utils.ts',
        },
      ],
      'check-file/folder-match-with-fex': [
        'error',
        {
          '*.test.{js,jsx,ts,tsx}': '**/__tests__/',
          '*.styled.{jsx,tsx}': '**/components/',
        },
      ],
      'check-file/filename-naming-convention': [
        'error',
        {
          '**/*.{jsx,tsx}': 'PASCAL_CASE',
          '**/*.{js,ts}': 'CAMEL_CASE',
        },
      ],
      'check-file/folder-naming-convention': [
        'error',
        {
          'src/components/*/': 'PASCAL_CASE',
          'src/!(components)/**/!(__tests__)/': 'CAMEL_CASE',
        },
      ],
    },

Two things stand out. Every rule is set to error, which makes these failures block a commit rather than warn. And the conventions are per file extension, so a React component in jsx or tsx is expected to be PASCAL_CASE while a plain module in js or ts is expected to be CAMEL_CASE, which is a convention that suits most component codebases but is stricter than many teams actually follow.

The plugin is registered under the name check-file, so the rule identifiers in the config always start with check-file/.

The same rules run under Oxlint, and version 3 broke legacy config

Two compatibility facts shape whether this fits your project.

First, the repository contains two example projects, an ESLint example at examples/eslint and an Oxlint example at examples/oxlint, and the package.json wires them as workspaces with scripts that lint each one. That means the plugin is not tied to the ESLint runtime in a way that prevents use with other linters. If your team is standardising on Oxlint for speed, the plugin has a documented configuration path for it, which is worth checking before you rule the plugin out on toolchain grounds.

Second, and more bluntly, the version 3 line only supports ESLint's flat configuration. For legacy configuration support you need version 2.x. That is a hard break rather than a deprecation, so a project still on.eslintrc has to either stay on the 2.x line or migrate its configuration before it can upgrade. The recent releases show v3.3.2 on 2026-07-18, v3.3.1 on 2025-11-03 and v3.3.0 on 2025-06-09, and the last push was on 2026-09-13.

The package itself is built with rollup from the lib/ directory and published as both CommonJS and ESM, with main at dist/index.cjs, module at dist/index.js and type declarations for each, and type set to module. The type field being module while a CommonJS build is still shipped is deliberate, so the plugin can be required from older tooling and imported from modern tooling.

Where the plugin is the wrong tool

The main limitation is that these rules fail on files you did not write, which makes adoption a migration rather than an installation.

Turning on filename-naming-convention across every file under src means every existing file that violates the convention becomes a lint error, including generated files, vendored directories, fixture directories and anything a colleague committed last week. The plugin offers no per-path exceptions beyond the glob keys themselves, and there is no grandfathering mechanism documented. The practical approach is to scope the rules tightly at first, as the example does by restricting the files pattern to everything under src, and widen only once the tree is clean.

The second limitation is scope. These rules check names and locations only. They do not check that file contents match the convention, that a directory is empty of dead code, or that a name is unique. If your real problem is duplicate module names or orphan files, this plugin does not address it.

The third is the convention vocabulary. The values are fixed names such as PASCAL_CASE and CAMEL_CASE. Teams whose convention is more specific, a domain prefix, a version suffix, a pattern that depends on the directory depth, cannot express that through the naming rules and would need the blocklist or folder match rules instead, or a separate script.

A related operational point: because the plugin runs inside ESLint, these rules only fire on files ESLint processes. Without the optional processor, YAML, markdown, images and other non-JavaScript assets are never checked, which is why the processor entry exists.

Editorial conclusion

Adopt eslint-plugin-check-file when your repository has an agreed naming convention that lint rules never touched, especially when index files and scattered test files are the problem, and skip it if your naming policy is enforced by a separate CI script you already maintain. Before enabling it, decide whether the whole tree is already compliant, because these rules fail on files you did not write, and confirm your ESLint version uses flat configuration, since version 3 and above dropped legacy config support and the legacy path is version 2.x.

Frequently asked questions

How do I install eslint-plugin-check-file?

Install ESLint first with npm i eslint --save-dev, then npm install eslint-plugin-check-file --save-dev. Both are dev dependencies, and the plugin supports ESLint's flat configuration.

Does eslint-plugin-check-file work with ESLint legacy configuration?

No. Version 3.x and above only support flat configuration, and the documentation says to use version 2.x if you need legacy configuration support.

What rules does eslint-plugin-check-file provide?

Five: no-index, which forbids a file named index, filename-blocklist for blocking filenames by pattern, folder-match-with-fex for requiring specified files to sit in specified folders, filename-naming-convention and folder-naming-convention for enforcing naming patterns.

How do I check the names of YAML or image files with eslint-plugin-check-file?

Add the optional processor to your flat config, pointing at the files ESLint would otherwise skip, for example a files pattern of YAML and webp files with processor: 'check-file/eslint-processor-check-file'.

Can eslint-plugin-check-file be used with Oxlint?

The repository contains an Oxlint example under examples/oxlint alongside the ESLint example, and the package.json has a script to lint both example workspaces, so the plugin is usable outside the ESLint runtime.

Official sources

  1. dukeluo/eslint-plugin-check-file on GitHub
  2. License: Apache-2.0
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/dukeluo-eslint-plugin-check-file.svg)](https://hysenlabs.com/projects/dukeluo-eslint-plugin-check-file)

Was this useful?