Skip to content
GitHubXDiscord

@triggery/eslint-plugin

ESLint plugin for Triggery: catches mis-use of createTrigger and the hook API, enforces conventions, and keeps trigger files readable as specs. Ships recommended and strict flat-config presets for ESLint 9.x.

npm bundle

pnpm add -D @triggery/eslint-plugin eslint typescript

Peer deps: eslint >= 9.0.0, typescript >= 5.0.0.

RuleRecommendedStrictAuto-fix
no-dynamic-iderrorerror
no-event-cascadeerrorerror
hook-ruleserrorerror
exhaustive-conditionswarnerror
exhaustive-requiredwarnerror
max-handler-sizewarn (≤50)error (≤30)
max-ports-per-triggerwarn (≤12)error (≤8)
prefer-named-hookoffwarn (≥3)

Flat config (ESLint 9.x):

eslint.config.js
import triggery from '@triggery/eslint-plugin';

export default [
  triggery.configs.recommended,
  // Or, dialled up:
  // triggery.configs.strict,
];

Cherry-picking individual rules:

import triggery from '@triggery/eslint-plugin';

export default [
  {
    plugins: { '@triggery': triggery },
    rules: {
      '@triggery/no-dynamic-id':       'error',
      '@triggery/no-event-cascade':    'error',
      '@triggery/max-handler-size':    ['warn', { max: 40 }],
    },
  },
];
  • no-dynamic-idcreateTrigger({ id }) must be a string literal. Trigger ids are registry keys, devtools labels, and graph anchors — they must be deterministic.
  • no-event-cascade — Disallows useEvent(...) inside a useAction(...) handler. Cascades are allowed at runtime, but writing them inline hides cross-trigger control flow.
  • hook-rules — Framework-neutral rules-of-hooks for useEvent / useCondition / useAction / useInlineTrigger.
  • exhaustive-conditions — Every name in required: [...] has a matching useCondition in the same file.
  • exhaustive-required — Every createTrigger({...}) call must include an explicit required: key (use required: [] if no gate is needed).
  • max-handler-size / max-ports-per-trigger — Keep triggers spec-like; reach for the extract-trigger codemod when they grow.