eslint-no-restricted

A utility for generating fine-grained no-restricted-syntax, no-restricted-globals, and no-restricted-properties ESLint rules with per-rule severity and dynamic messages.

Library
npm
v0.1.2
15stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
38/100Needs Attention
Development Activity52
Maintenance28
Community16
Maturity44
Momentum12

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
70/100Good
Architecture85
Code Quality82
Innovation78
Learning Curve35

eslint-no-restricted is a small utility that generates ESLint rule plugins for banning specific syntax patterns, global variables, or object properties. Rather than lumping every restriction into ESLint’s built-in no-restricted-syntax, no-restricted-globals, and no-restricted-properties rules, it creates one distinct rule per selector, global, or property — so each restriction can be configured with its own severity, enabled or disabled per file or folder, and silenced independently with a single disable comment.

The library also supports dynamic message placeholders via a messageData callback, letting rule authors surface contextual information (like the exact variable name or literal value flagged) in the reported error message for a clearer developer experience. It ships a fully-typed API built on @typescript-eslint/utils, targets ESLint’s flat config format, and auto-generates a recommended config from the rules you define.

What You Get

  • Three rule-creation entry points — createSyntax, createGlobals, createProperties — for different restriction targets
  • Auto-generated recommended flat config bundling every rule you define
  • Per-rule severity control (error/warn/off) via a defaultLevel option
  • Dynamic message placeholders through a messageData callback for contextual error text
  • Full TypeScript typings built on @typescript-eslint/utils and TSESTree/TSESLint types
  • Support for a custom plugin name to avoid collisions when publishing your own rule sets

Common Use Cases

  • Banning deprecated globals or dangerous object properties across a codebase with per-rule severity
  • Enforcing internal API conventions by restricting specific object.property access patterns
  • Rolling out new restrictions incrementally at warn severity before promoting them to error
  • Building and publishing a custom internal ESLint plugin with descriptive, contextual error messages

Under The Hood

Architecture The library is organized as three thin per-restriction-type modules (syntax.ts, globals.ts, properties.ts) that each define a config type and a createRule function, delegating the actual ESLint rule object construction to a single shared createPlugin factory in shared.ts. createPlugin takes a plugin name, an array of rule configs, and a createRule callback, and assembles the ESLint flat-config Plugin shape (configs.recommended, meta, rules) generically — each restriction type only supplies its own matching logic (ESQuery selectors for syntax, scope-variable lookups for globals, MemberExpression matching for properties) against a shared RuleCreateFunction contract. index.ts is a thin re-export barrel exposing all three creators under one namespace. Adding a fourth restriction type would only require a new file implementing createRule and reusing shared.createPlugin, with no changes to the other modules — a clean, low-coupling design typical of focused utility libraries.

Tech Stack Written in TypeScript ^5.6 targeting Node ^20.9 or >=22, and built on @typescript-eslint/utils ^8.56 / @typescript-eslint/types ^8.56 for its TSESTree/TSESLint typings and ESLintUtils.RuleCreator. Its only production dependency surface is a peer dependency on eslint (^8.57 || ^9 || ^10), keeping runtime footprint minimal. Build tooling is plain tsc (no bundler) producing CJS output via a dedicated tsconfig.build.json, with rimraf for clean builds. The dev stack leans heavily on static analysis — ESLint 10 with an extensive plugin set (typescript-eslint, eslint-plugin-perfectionist, eslint-plugin-regexp, plugins for JSON/YAML/Markdown/package.json), knip for unused-export detection, cspell for spellchecking, prettier with several plugins, and @arethetypeswrong/cli to validate published package exports. Tests run under vitest.

Code Quality Tests live in tests/ (syntax.test.ts, globals.test.ts, properties.test.ts, plus a shared utils.ts helper) and run under vitest, using the real Linter from @typescript-eslint/utils/ts-eslint to execute generated rules against sample code and assert against inline snapshots — testing actual output rather than mocked internals. Error handling is minimal but deliberate: createPlugin throws synchronously at plugin-construction time if a rule declares a {{placeholder}} message without a messageData function, catching a real misconfiguration early. Naming is consistent across modules (createX/RuleConfig/CreateFn), and generics (TNode, TRules, TName) keep rule names and node types coherent through the shared factory. A ci script chains build, three separate typecheck targets, lint, knip, format-check, and spellcheck, with CI configured under .github/.

API Design The public surface is deliberately small: three functions that share one call shape (create(...rules) or create(pluginName, ...rules)), so learning one teaches all three. Config objects are declarative rather than requiring subclassing or visitor boilerplate, and the generated recommended config drops straight into a flat eslint.config.mjs array. The messageData placeholder mechanism is a genuinely useful DX touch, turning generic “banned pattern” messages into ones that quote back the actual flagged code. Documentation lives entirely in the README but is thorough, with worked examples for all three modules; there’s no dedicated docs site, per-rule doc URLs are left to the rule author, and no example directory or changelog ships with the package.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search