Lesson 15 / 27

Custom ESLint Rules

Write a custom ESLint rule inside a local plugin to enforce conventions your codebase needs.

When to write custom rules

Standard rules don't cover your codebase's conventions? Write a custom rule to enforce them. Examples: require specific naming patterns, forbid certain libraries, enforce architectural layers.

Simple custom rule

A custom rule in a local plugin that forbids console.log, wired into flat config.

// eslint.config.js
const local = {
  rules: {
    'no-prod-console': {
      meta: { type: 'problem', schema: [] },
      create(context) {
        return {
          CallExpression(node) {
            const c = node.callee;
            if (c.type === 'MemberExpression' && c.object.name === 'console' && c.property.name === 'log') {
              context.report({ node, message: 'console.log is not allowed in production code' });
            }
          },
        };
      },
    },
  },
};

export default [
  { plugins: { local }, rules: { 'local/no-prod-console': 'error' } },
  { files: ['**/*.test.js'], rules: { 'local/no-prod-console': 'off' } },
];

Output:

Custom rule defined: forbids console.log in prod

Prefer plugins over rules

If a rule is complex or reusable, publish it as an eslint-plugin. Simple team rules can live in a local plugin object inside eslint.config.js.

Quick check

Quick check: When should you write a custom ESLint rule?

  • When your codebase has unique conventions standard rules don't cover.
  • For all projects.
  • Only for large teams.
  • To disable core rules
Answer

When your codebase has unique conventions standard rules don't cover. — Custom rules automate enforcement of architectural or style decisions unique to your team.