Skip to content

Latest commit

 

History

History

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

README.md

eslint-plugin-kerfjs

ESLint rules that enforce kerf's hard rules. Catches AI-shaped bugs at edit time, before they reach tsc or the runtime dev-warns.

This plugin sits alongside two other defense layers shipped by kerfjs:

Layer Catches When
tsc --noEmit with strict typings Hard Rules 8 (partial-set), most type errors Build time
Opt-in dev-warns (KERF_DEV_WARN_*) Hard Rules 4 (rebuilt listeners), 7 (untracked signals), 8 (narrow set) Runtime
This plugin Hard Rules 2, 5, 6, 10, 12 — AST-shaped antipatterns; plus rename-safety / raw()-audit nudges and a project-hygiene check for the bundled AI-assistant configs Edit time

All but one rule are AST-only — no @typescript-eslint/parser service dependency is required by the plugin (consumers configure their own parser). The exception, ai-assistant-configs, reads the filesystem instead of the AST and runs once per lint pass.

Install

npm install --save-dev eslint-plugin-kerfjs

Supported ESLint versions

peerDependencies declares ^9.0.0 || ^10.0.0, and that is a tested range rather than an optimistic one: the rule suite runs against the latest release of each of those majors in CI on every push. A major is added to the range only after the suite has passed on it.

A version outside the range is not "probably fine" — it is one nobody has run. If you need a newer major, open an issue rather than forcing the peer; expanding the range is a one-line change once the matrix is green.

ESLint 8 is not supported. This package is ESM-only, and ESLint 8 loads plugins for .eslintrc configs with require() — so extends: ["plugin:kerfjs/..."] fails to resolve the plugin at all. ESLint 8's opt-in flat-config mode can load it, but that is not the default path an ESLint 8 project is on, so the range does not claim it.

Configure (flat config, ESLint v9+)

// eslint.config.js
import kerfjs from 'eslint-plugin-kerfjs';
import tsParser from '@typescript-eslint/parser';

export default [
  {
    files: ['**/*.ts', '**/*.tsx'],
    languageOptions: {
      parser: tsParser,
      parserOptions: { ecmaFeatures: { jsx: true } },
    },
  },
  kerfjs.configs.recommended,
];

Legacy .eslintrc configs are not supported

The package is ESM-only. ESLint's .eslintrc system loads plugins with require(), which cannot load an ESM package, so extends: ["plugin:kerfjs/legacy-recommended"] fails with "couldn't find the config to extend from" on ESLint 8 and on ESLint 9's legacy mode.

Use flat config (eslint.config.js), shown above. The legacy-recommended export still exists in the package but is unreachable through any config system — treat it as deprecated.

Rules

Rule Hard Rule Severity (recommended)
no-inline-jsx-event-handlers 10 — use data-action + delegate() error
require-data-key-in-each 2 — data-key per item error
require-delegate-disposer 5 — capture delegate() disposers when scope < page warn
no-nested-mount 6 — one mount() per root error
prefer-module-jsx-augmentation 12 — augment kerfjs/jsx-runtime, not global error
prefer-attr-selector — (rename-safety nudge for delegate() selectors) warn
no-raw-with-dynamic-arg — (XSS audit trail) warn
ai-assistant-configs — (project hygiene) warn

The "Hard Rule" column refers to the numbered rules in docs/ai/usage-guide.md on the main kerf repo. no-raw-with-dynamic-arg and ai-assistant-configs don't map to numbered Hard Rules — the former creates an audit trail for every dynamic raw() call site (potential XSS); the latter checks that the bundled AI-assistant configs are installed and current. See docs/12-ai-assistant-configs.md on the main kerf repo for the AI-configs design.

Why these rules, and not more

Rules that need flow analysis (signal reads outside render — Rule 8), call-graph analysis (addEventListener inside the mount tree — Rule 4), or type information (partial-set against multi-key state — Rule 9) are already covered by the opt-in dev-warns and strict TS. Duplicating them here would mean either high false-positive rates without type info, or a parserServices dependency that complicates consumer setup.

When a real bug ships that the existing defense stack misses AND a new lint rule would not false-positive on legitimate code, file an issue on the main kerf repo.

Develop / test

npm install
npm test

The AST rules' test suites use ESLint's RuleTester with @typescript-eslint/parser. The ai-assistant-configs tests are filesystem-driven — they build temp project roots with fixture node_modules/kerfjs/ai/ bundles and drive the rule's classifier directly, since RuleTester doesn't simulate the filesystem.

License

MIT