# Plugins reference `eslint-config-mocg` is strict by design. It does not assemble a handful of "recommended" presets and call it a day — it layers a couple of dozen plugins, each chosen to catch a specific class of mistake before it reaches review or production. This page is the map: for every plugin we ship, what category of problems it catches and what it actually ensures for the team — not just its name. Plugins fall into three groups. **Core plugins** are bundled as regular `dependencies` and are always active in the base Node/TypeScript config. **Framework plugins** and **add-on plugins** are optional `peerDependencies` — you install them only for the stacks you use, and they activate automatically when detected. ::: tip Every rule cited below was read out of the ruleset source under `src/`. Where a plugin is enabled through its own `recommended` preset, that is noted as such rather than enumerating rules the config does not itself set. ::: ## Core plugins (always on) These run on every file in every project. They are bundled with the package, so there is nothing extra to install. ### Code correctness & best practices #### `@eslint/js` The ESLint core recommended ruleset (`pluginJs.configs.recommended`). This is the floor: it catches outright bugs such as unreachable code, duplicate object keys, comparing against `NaN`, and `case` fall-through. Everything else builds on top of it. #### Owned "best-practices" ruleset (core ESLint rules) Defined in `src/config/node/best-practices.eslint.ts`, this is not a plugin but a hand-maintained set of core ESLint rules that replaces the now-unmaintained `eslint-config-airbnb-base`. It ensures the team keeps Airbnb's battle-tested logic-level conventions without depending on a dead package. Representative rules: `array-callback-return`, `no-param-reassign` (with carve-outs for accumulators and request/response objects), `consistent-return`, `no-await-in-loop`, `prefer-template`, `prefer-destructuring`, and a large `no-restricted-globals` list that blocks accidental use of browser globals like `name` or `location` in Node code. #### `eslint-plugin-sonarjs` SonarSource's code-quality and bug-detection rules (`recommended` preset). It ensures the team avoids cognitive-complexity traps and subtle logic bugs: duplicated branches in conditionals, identical expressions on both sides of an operator, collapsible `if` statements, and dead/redundant code. The config tunes a few rules down to warnings (`sonarjs/function-return-type`, `sonarjs/todo-tag`) and turns off opinions that fight the rest of the stack (`no-commented-code`, `redundant-type-aliases`). #### `eslint-plugin-unicorn` A broad collection of "modern, more correct JavaScript" rules (`recommended` preset). It ensures the codebase prefers current platform APIs and consistent idioms over legacy patterns — for example preferring `node:` protocol imports, modern `Array`/`String` methods, and explicit error handling. The config relaxes a few opinionated rules (`no-null`, `no-array-for-each`, `prefer-top-level-await`) and configures `prevent-abbreviations` with an allow-list (`spec`, `param`, `e2e`, `rootDir`, `props`/`Props`) so meaningful short names — including the universal React `*Props` convention — are not flagged. #### `eslint-plugin-promise` Promise and async correctness (`flat/recommended` preset). It ensures `Promise` chains are not silently broken: every `.then` returns or handles, `new Promise` executors are used correctly, and you do not accidentally nest or forget callbacks. This catches a whole category of "the await did nothing" bugs that type-checking alone misses. #### `eslint-plugin-n` Node.js-specific correctness (`flat/recommended-module` preset). It ensures code targets the Node version range the project actually supports: it flags deprecated Node APIs, unsupported syntax/built-ins for the declared engines, missing or unpublished imports, and `process.exit()` in library code. Scripts and config files relax these (see `src/config/node/scripts.eslint.ts` and `eslint-rules.eslint.ts`) since they run on the local toolchain rather than the shipped runtime. #### `eslint-plugin-regexp` Regular-expression correctness and safety (`flat/recommended` preset). It ensures regexes are well-formed and efficient: it catches redundant escapes, unintended character classes, and — importantly — patterns prone to catastrophic backtracking (ReDoS). This protects against both bugs and a real denial-of-service vector. #### `eslint-plugin-depend` Dependency-weight hygiene (`flat/recommended` preset). It ensures the team does not reach for a heavyweight package when a native or lighter alternative exists — for example suggesting native optional chaining over `lodash.get`, or built-in crypto over a UUID library for simple IDs. The benefit is smaller installs and fewer transitive dependencies. It is disabled on config files where dev-only tooling imports are expected. #### `eslint-plugin-lintlord` A custom rules plugin (`strict` preset). Here it ensures all logging goes through the project logger rather than ad-hoc `console.*`: `lintlord/prefer-logger` runs in `mode: 'all'`, flagging every `console` method. Scripts opt out, since CLI tools are expected to write to stdout. #### Owned "custom-style" logic rules In `src/config/node/custom-style.eslint.ts`, another set of core ESLint rules covering logic-level style (not formatting, which Prettier owns). It ensures consistent, defensive code: `eqeqeq` (with `null` ignored), `curly: all`, `no-eval`, `no-console` as an error, `prefer-const`, `no-var`, `no-throw-literal`, `radix`, and `no-use-before-define`. ### Imports & module hygiene #### `eslint-plugin-import-x` A maintained, flat-config-native fork of `eslint-plugin-import`, registered under the `import-x` namespace. It ensures imports actually resolve to something real and the module graph stays sane: it flags imports of names that an exporting module does not provide (`import-x/named`), duplicate imports, self-imports, circular dependencies (`import-x/no-cycle`), absolute paths, and importing extraneous (non-declared) dependencies. The `no-extraneous-dependencies` rule allows `devDependencies` in test and config files but errors on stray runtime imports elsewhere. #### `eslint-plugin-simple-import-sort` Deterministic import ordering. It ensures every file's imports are grouped and sorted the same way, removing an entire category of merge conflicts and review noise. The grouping is project-aware: it puts `node:` built-ins first, then NestJS, then React, then other npm packages, then **internal alias groups that are generated dynamically from your `tsconfig` paths**, then side-effect imports, then relative imports, then styles. #### `@dword-design/eslint-plugin-import-alias` Path-alias enforcement (`recommended` preset). It ensures deep relative imports (`../../../utils`) are rewritten to the project's `tsconfig` path aliases via `import-alias/prefer-alias`. The alias map is built automatically from `tsconfig` `paths` + `baseUrl`, so the rule only activates when a project defines aliases — otherwise the config contributes nothing. #### `eslint-plugin-unused-imports` Dead-import removal. `unused-imports/no-unused-imports` ensures imports that are no longer referenced are reported and auto-removed on `--fix`, keeping module headers honest and avoiding accidental coupling. #### `eslint-plugin-no-barrel-files` Barrel-file prevention (`flat` preset). It ensures the team does not create `index` files that re-export a whole directory. Barrel files defeat tree-shaking and inflate bundle sizes by pulling in modules that are never actually used. ### Style & formatting #### `eslint-plugin-prettier` + `eslint-config-prettier` Formatting as a lint rule, via `eslint-plugin-prettier/recommended`. It ensures Prettier is the single source of truth for formatting: Prettier violations surface as ESLint errors, and `eslint-config-prettier` (bundled in the recommended preset) turns off every ESLint rule that would otherwise fight Prettier. The team never argues about quotes, semicolons, or wrapping. #### `@stylistic/eslint-plugin` The stylistic rules that survive Prettier — the layout decisions Prettier does not make. It ensures consistent vertical rhythm: `@stylistic/lines-between-class-members` requires blank lines between class members, and a detailed `@stylistic/padding-line-between-statements` configuration enforces blank lines around returns, blocks, multiline declarations, and import boundaries while keeping `switch` cases tight. #### `eslint-plugin-perfectionist` Sorting and organization (`recommended-natural` preset, heavily tuned). Rather than sorting everything, this config narrows it to the cases the team cares about: `perfectionist/sort-jsx-props` (with a priority group so `key`, `className`, `title`, etc. come first) and `perfectionist/sort-union-types` (so TypeScript unions follow a consistent type-category order). Most other perfectionist sorters are explicitly disabled so they do not conflict with `simple-import-sort` or become noisy. ### Security #### `eslint-plugin-security` Node.js security heuristics (`recommended` preset). It ensures risky patterns get a second look: non-literal `fs` filenames (path traversal), non-literal `RegExp` (ReDoS), `child_process` with dynamic input, unsafe `eval`-like calls, and pseudo-random values used where cryptographic randomness is expected. #### `eslint-plugin-no-secrets` Entropy-based secret detection. `no-secrets/no-secrets` ensures high-entropy strings — API keys, tokens, private-key material — are not accidentally committed in source. It is a cheap last line of defense against leaking credentials. ### Documentation #### `eslint-plugin-jsdoc` JSDoc completeness and correctness. It ensures public surface area is documented and that the docs stay in sync with the code. The config applies the TypeScript-aware preset (`flat/recommended-typescript-error`) to `.ts`/`.tsx` files and the plain preset (`flat/recommended-error`) to JavaScript, and on top of both requires a description (`jsdoc/require-description`). Test files relax these requirements. ### TypeScript & type-aware #### `typescript-eslint` The TypeScript engine of the whole config — parser plus rules. It ensures TypeScript code is held to the strictest practical standard using **type-aware linting**: `src/config/typescript/project.eslint.ts` wires up the parser with `projectService: true`, so rules can read the type checker, not just the syntax tree. The ruleset applies both `strictTypeChecked` and `stylisticTypeChecked` presets to `*.{ts,tsx,mts,cts}` files. On top of the presets, `src/config/typescript/overrides.eslint.ts` enforces team conventions: `consistent-type-definitions: interface`, `consistent-type-imports` (separate `import type`), `switch-exhaustiveness-check`, `prefer-readonly`, and the typed replacements (`@typescript-eslint/no-unused-vars`, `no-shadow`, `no-useless-constructor`) for their core counterparts, which are turned off on TS files so they do not double-report. #### `eslint-config-naming` A shareable naming-convention config layered onto the `@typescript-eslint` plugin, scoped to TypeScript files (`src/config/typescript/naming.eslint.ts`). It ensures consistent identifier naming across the codebase — types, interfaces, variables, and members — going beyond what the core `camelcase` rule (which covers plain `.js`/`.ts`) can express. ## Framework plugins (optional peers) These are optional `peerDependencies`. Install them only for the frameworks you use; the config activates the matching ruleset automatically when the stack is detected. ### React #### `eslint-plugin-react` The canonical React linting plugin (`recommended` + `jsx-runtime` presets). It ensures correct JSX and component usage: valid prop types and usage, no missing `key` props in lists, no deprecated lifecycle patterns, and — via `jsx-runtime` — that the new automatic JSX transform is respected (no spurious "React must be in scope" errors). The config resolves the React version from your installed `react` package and pins it in `settings.react.version` (it does **not** use the plugin's `'detect'` mode, whose version detector calls a `context.getFilename()` API removed in modern ESLint). #### `eslint-plugin-react-hooks` Rules of Hooks enforcement (`recommended-latest` preset). It ensures Hooks are only called at the top level and only from React functions, and that effect dependency arrays are complete. This catches the single most common source of subtle React bugs — stale closures and conditionally-called hooks. #### `eslint-plugin-react-refresh` (not in the React stack — a bundler add-on) Fast Refresh safety. It flags exports that would break hot module replacement (for example mixing component and non-component exports in one file). Because Fast Refresh is a bundler/HMR concern, the **React stack is pristine and does not load it** — it is supplied where it actually applies: the **`vite` add-on** (auto-detected from `vite`) uses the `vite` preset (`allowConstantExport`), and the **Next.js stack** uses the `next` preset (allowing Next's route exports). See [Stacks → Vite Fast Refresh](/guide/stacks#vite-fast-refresh). #### `eslint-plugin-react-compiler` (opt-in — not part of the React stack) React Compiler validation. Unlike the three plugins above, this is **not** activated by the React stack and is **not** auto-installed: it is an optional peer that `mocg()` never loads. Enable it explicitly via the `eslint-config-mocg/react-compiler` export (see [Stacks → React Compiler](/guide/stacks#react-compiler-opt-in)) only when your project runs the React 19 compiler. When enabled, `react-compiler/react-compiler` ensures components follow the rules the compiler depends on for safe auto-memoization, surfacing code the compiler would otherwise bail out on. ### Next.js #### `@next/eslint-plugin-next` The official Next.js plugin (`core-web-vitals` config). The Next stack is **React + Next** — it composes the React plugins above and layers this plugin on top. The config applies `core-web-vitals`, which already contains every `recommended` rule plus the Core Web Vitals warn→error upgrades (`@next/next/no-html-link-for-pages`, `@next/next/no-sync-scripts`). It catches Next-specific mistakes the framework cares about: `` instead of `next/image`, `` instead of `next/link` for internal routes, synchronous scripts, `next/head`/`next/document` misuse, missing `next/script` ids, and font/Polyfill pitfalls. The config uses this plugin **directly** rather than `eslint-config-next` (which would re-bundle react/react-hooks/typescript-eslint and conflict with this package's own copies). The Next stack also allows the App Router and Pages Router export names for Fast Refresh and relaxes `jsdoc/require-jsdoc` for `route.ts`/`middleware.ts`. ### Vue #### `eslint-plugin-vue` + `vue-eslint-parser` Vue 3 Single-File-Component linting (`flat/recommended` preset). The plugin ensures `