JS Guide
HomeQuestionsTopicsCompaniesResources
BookmarksSearch

Built for developers preparing for JavaScript, React & TypeScript interviews.

ResourcesQuestionsSupport
HomeQuestionsSearchProgress
HomeTopicstoolingCustom ESLint Rules & Plugins
PrevNext
tooling
advanced
15 min read

Custom ESLint Rules & Plugins

ast
ast-explorer
custom-rules
eslint
plugins
static-analysis
visitor-pattern

Custom ESLint rules use AST visitors to enforce project-specific coding standards, with each rule exporting a meta object for documentation and a create function that returns visitor methods for specific syntax node types.

Key Points

1AST-Based Analysis

ESLint rules operate on the Abstract Syntax Tree, where each node represents a syntactic construct like VariableDeclaration, CallExpression, or MemberExpression.

2Rule Meta and Create

Rules export a meta object (docs, type, fixable, schema) and a create function that returns visitor methods for specific AST node types.

3Visitor Pattern

ESLint traverses the AST and calls your visitor functions for matching node types — you call context.report() when a violation is found.

4Plugin Packaging

Plugins bundle multiple rules into an npm package, exporting a rules object and optionally recommended configs for easy adoption.

5RuleTester for Verification

ESLint's built-in RuleTester lets you define valid and invalid code examples with expected errors, enabling test-driven rule development.

What You'll Learn

  • Explain the structure of a custom ESLint rule including meta and create functions
  • Use AST Explorer to identify the correct node types for a given code pattern
  • Write a custom rule with auto-fix capability using the fixer API
  • Package multiple rules into an ESLint plugin with shared configs

Deep Dive

ESLint's power comes from its extensibility. While the ecosystem provides thousands of community rules, many teams need custom rules to enforce project-specific conventions — like banning certain API usage patterns, enforcing naming conventions for specific file types, or ensuring architectural boundaries are respected. Understanding how to write custom rules demonstrates deep knowledge of how static analysis works.

Abstract Syntax Trees (AST)

Every ESLint rule operates on the Abstract Syntax Tree — a tree representation of your source code where each node represents a syntactic construct. For example, const x = 5 becomes a VariableDeclaration node containing a VariableDeclarator with an Identifier (x) and a Literal (5). AST Explorer (astexplorer.net) is the essential tool for developing custom rules — it lets you paste code and see the resulting AST in real time.

Rule Structure

An ESLint rule exports an object with two properties: meta and create. The meta object contains documentation (description, category, URL), the type (problem, suggestion, or layout), whether the rule is auto-fixable (fixable: 'code' or fixable: 'whitespace'), and an optional JSON schema for rule options. The create function receives a context object and returns a visitor object — an object whose keys are AST node types and whose values are functions called when that node type is encountered.

Visitor Pattern

ESLint traverses the AST from top to bottom (and optionally back up). Your rule declares which node types it cares about, and ESLint calls your visitor function for each matching node. For example, to ban console.log, you visit MemberExpression nodes and check if the object is console and the property is log. When you find a violation, you call context.report() with the offending node and a message. For auto-fixable rules, you also provide a fix function that receives a fixer object with methods like replaceText, insertTextBefore, and remove.

Plugin Structure

An ESLint plugin is an npm package that bundles multiple rules (and optionally shared configs and processors). The package exports a rules object mapping rule names to rule definitions. With ESLint's new flat config system, plugins are plain objects imported directly — no more naming conventions or eslint-plugin- prefixes required. A plugin can also export configs for recommended sets of rules.

Testing Custom Rules

ESLint provides RuleTester, a built-in test utility that makes testing rules straightforward. You define arrays of valid and invalid code examples. For invalid cases, you specify the expected error messages and, for fixable rules, the expected output after fixing. This makes rule development highly test-driven.

Practical Examples

Common custom rules include: banning specific imports (e.g., preventing direct lodash imports in favor of lodash-es), enforcing data-testid attributes on interactive elements for testing, requiring error boundaries around async components, and enforcing file naming conventions based on directory structure.

Key Interview Distinction

ESLint rules are static analysis — they examine code structure without executing it. This means they can catch patterns like missing error handling or incorrect API usage at development time, but they cannot detect runtime behavior. The visitor pattern is what makes ESLint rules composable — each rule only declares the node types it cares about, and ESLint efficiently routes nodes to the appropriate visitors during a single AST traversal.

Fun Fact

AST Explorer (astexplorer.net) supports over 30 different parsers across languages including JavaScript, TypeScript, CSS, GraphQL, and even SQL. It was originally created by Felix Kling in 2014 and has become the single most important tool for anyone building code transformation tools or linter rules.

Learn These First

ESLint Configuration & Static Analysis

beginner

Continue Learning

Transpilation with Babel & SWC

advanced

Code Formatting with Prettier

beginner

Practice What You Learned

How do you create custom ESLint rules and plugins?
senior
custom
Create custom ESLint rules by writing AST visitors that detect patterns and report errors. Rules receive context with report() for violations. Package multiple rules as a plugin with rules and recommended configs. Use AST Explorer to understand code structure.
Previous
Docker for JavaScript Applications
Next
Debugging with Chrome DevTools
PrevNext