To create a custom ESLint rule, you need to create a rule directory and configure it.eslintrc.js is loaded through require or local plug-in; 2. To write rules, you need to define meta and create functions, and check the code pattern through AST traversal, such as prohibiting import of specific paths; 3. Use eslint-rule-tester to write test cases to ensure that the rules behave correctly in valid and invalid code; 4. Use AST deep analysis to implement advanced functions, such as restricting function calls, naming specifications or environment variable access; 5. Make rules reusable through schema configuration, and support sharing across projects in private npm packages or monorepo, ultimately implementing automated enforcement of team coding specifications.
If you're working on a JavaScript or TypeScript project with specific coding standards that existing ESLint rules don't fully cover, creating custom ESLint rules is a powerful way to enforce your team's best practices. While ESLint comes with a rich set of built-in rules and plugins, sometimes you need something tailored—like banner certain function calls, enforcing naming patterns, or validating file structure.

Here's how to create and use custom ESLint rules in your project effectively.
1. Set Up a Custom Rule Directory
Start by organizing your custom rules. ESLint allows you to define rules locally in your project using a plugin-like structure.

Create a directory for your rules, eg:
mkdir -p .eslint/rules
Then, make sure your ESLint configuration can find them. You don't need to publish a full plugin—just use ESLint's rules
object directly or load them via a plugin path.

In .eslintrc.js
, you can load rules using require
:
const myCustomRule = require('./.eslint/rules/no-internal-import'); module.exports = { rules: { 'no-internal-import': ['error', { disallowedPaths: ['src/utils/internal'] }], }, // ... other config };
Alternatively, define a local plugin:
plugins: { 'my-rules': { rules: { 'no-internal-import': myCustomRule, }, }, }, rules: { 'my-rules/no-internal-import': 'error', }
2. Write a Basic Custom Rule
A rule is an object with a meta
property and a create
function that defines behavior during AST traversal.
Let's create a rule that prevents imports from internal utility folders unless explicitly allowed.
.eslint/rules/no-internal-import.js
module.exports = { meta: { type: 'suggestion', docs: { description: 'disallow imports from internal utility folders', }, schema: [ { type: 'object', properties: { disallowedPaths: { type: 'array', items: { type: 'string' }, }, }, additionalProperties: false, }, ], }, create(context) { const options = context.options[0] || {}; const disallowedPaths = options.disallowedPaths || []; return { ImportDeclaration(node) { const importPath = node.source.value; for (const path of disallowedPaths) { if (importPath.startsWith(path)) { context.report({ node, message: `Import from disallowed path: ${path}`, }); } } }, }; }, };
This rule checks every import
statement and warns if it starts with a path in the disallowedPaths
list.
3. Test Your Custom Rule
Testing ensures your rule behaves correctly and doesn't break with edge cases.
Use ESLint's testing tools:
npm install eslint eslint-plugin-node eslint-rule-tester --save-dev
Create a test file: .eslint/rules/__tests__/no-internal-import.test.js
const { RuleTester } = require('eslint'); const rule = require('../no-internal-import'); const ruleTester = new RuleTester({ parserOptions: { ecmaVersion: 2021, sourceType: 'module' } }); ruleTester.run('no-internal-import', rule, { valid: [ "import { util } from 'src/utils/public';", { code: "import { util } from 'src/helpers';", options: [{ disallowedPaths: ['src/utils/internal'] }] }, ], invalid: [ { code: "import internal from 'src/utils/internal/helper';", errors: [{ message: "Import from disallowed path: src/utils/internal" }], }, ], });
Run the test via a script in package.json
:
"scripts": { "test:eslint": "node .eslint/rules/__tests__/no-internal-import.test.js" }
4. Use Advanced AST Patterns
Custom rules shine when you need deep code analysis. For example:
- Enforce function call restrictions: ban
console.log
in production files. - Validate naming conventions: component files must end in
.tsx
if they export a React component. - Check for side effects: prevent direct access to environment variables outside config files.
Example: ban process.env
outside allowed files.
MemberExpression(node) { if ( node.object.type === 'Identifier' && node.object.name === 'process' && node.property.name === 'env' && !context.getFilename().includes('config/') ) { context.report({ node, message: 'Direct access to process.env is only allowed in config files.', }); } }
You can access file paths, comments, and even scope information via context
.
5. Make Rules Configurable and Reusable
Good custom rules are flexible. Use the schema
in meta
to allow options:
schema: [ { type: 'object', properties: { exemptFiles: { type: 'array', items: { type: 'string' } }, }, }, ],
Then check context.getFilename()
in your logic to apply examples.
Also, consider sharing rules across projects by packaging them in a private npm module or monorepo package.
Creating custom ESLint rules isn't hard once you understand the AST and ESLint's plugin model. Start small—ban a pattern you see often—then expand as needed. The payoff is cleaner, more consistent code with automated enforcement.
Basically, if your team keeps making the same mistake in code reviews, it's probably time to write a rule for it.
The above is the detailed content of Creating Custom ESLint Rules for Your Project. For more information, please follow other related articles on the PHP Chinese website!

Hot AI Tools

Undress AI Tool
Undress images for free

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Clothoff.io
AI clothes remover

Video Face Swap
Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Hot Tools

Notepad++7.3.1
Easy-to-use and free code editor

SublimeText3 Chinese version
Chinese version, very easy to use

Zend Studio 13.0.1
Powerful PHP integrated development environment

Dreamweaver CS6
Visual web development tools

SublimeText3 Mac version
God-level code editing software (SublimeText3)

How to delete eslint from react: 1. Execute the "npm run eject" command; 2. Modify the code in package.json to ""eslintConfig": {"extends": ["react-app","react-app/jest" ],"rules": {"no-undef": "off"...}"; 3. Restart the project.

As a very popular scripting language, PHP has powerful function library support. Its function naming conventions and rules have an important impact on development efficiency and code readability. This article will introduce the naming conventions and rules of PHP functions. 1. Naming style In PHP, function names need to strictly comply with naming specifications and rules. The specifications mainly include two aspects: naming style and naming rules. 1. Underline nomenclature Underline nomenclature is the most commonly used way to name PHP functions and is also an officially recommended way. Function names that follow this pattern

In C/C++, the pointer comparison rules are as follows: pointers pointing to the same object are equal. Pointers to different objects are not equal. Exception: Pointers to null addresses are equal.

Buried points have always been an important part of the H5 project, and buried point data is an important basis for later business improvement and technical optimization. In daily work, students from product or business departments often come to ask, "What are the hidden points in this project now?", "Where is this hidden point used?" Questions like this are basically asked and checked. The code is very inefficient.

An in-depth understanding of the definitions and rules of Python identifiers requires specific code examples. Python is a concise and powerful programming language with a wide range of applications. In Python programming, identifiers play a vital role. This article will delve into the definition and rules of Python identifiers and provide specific code examples to help readers better understand and apply them. First, let’s understand the definition of Python identifiers. In Python, an identifier can be the name of a variable, function, class, module, etc.

Project introduction iptables is a free packet filtering firewall software under Linux system, which can realize packet filtering, packet redirection and network address translation and other functions. It is an efficient and flexible solution that replaces expensive commercial firewalls. iptables has powerful configuration options and rule settings, allowing users to finely control network traffic according to their own needs and improve network security and performance. The rules of iptables actually refer to the conditions predefined by the network administrator. The rules are generally defined as "If the data packet header meets such conditions, process the data packet in this way." The rules are stored in the packet filtering table in the kernel space. These rules respectively specify the source address, destination address, transmission protocol (such as TCP, U

With the continuous development of front-end technology, the problems we face have gradually become more complex, which not only requires our code to have a reasonable structure and good modular design, but also requires code maintainability and execution efficiency. In this process, how to ensure the quality and standardization of the code has become a difficult problem. Fortunately, the emergence of code standardization and bug detection tools provides us with effective solutions. Using ESLint for code standardization and bug detection in the Vue.js framework has become a common choice. 1. ESLint

The rules of flexible layout include: 1. Declaration of containers and items; 2. Main axis and cross axis; 3. Alignment and distribution; 4. Properties of flexible items; 5. Line wrapping and reverse; 6. Space distribution and size adjustment; 7 , Cross-axis order; 8. Cross-axis alignment; 9. Additional rules for flexible containers; 10. Nested flexible containers, etc. Detailed introduction: 1. Declaration of containers and items. In flexible layout, containers are used to contain items. The container can be any block-level element; 2. Main axis and cross axis. Items in flexible layout are arranged on the main axis and cross axis. ;3. Alignment and distribution, etc.
