{"id":14973156,"url":"https://github.com/emmanueldemey/eslint-plugin-angular","last_synced_at":"2026-03-02T02:01:42.377Z","repository":{"id":26424474,"uuid":"29874861","full_name":"EmmanuelDemey/eslint-plugin-angular","owner":"EmmanuelDemey","description":"ESLint plugin for AngularJS applications","archived":false,"fork":false,"pushed_at":"2025-11-14T10:22:39.000Z","size":1700,"stargazers_count":620,"open_issues_count":74,"forks_count":128,"subscribers_count":16,"default_branch":"master","last_synced_at":"2026-01-14T17:08:16.534Z","etag":null,"topics":["angularjs","eslint-plugin","javascript"],"latest_commit_sha":null,"homepage":"https://www.npmjs.com/package/eslint-plugin-angular","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/EmmanuelDemey.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2015-01-26T18:22:06.000Z","updated_at":"2025-11-14T10:22:42.000Z","dependencies_parsed_at":"2024-06-18T12:15:48.008Z","dependency_job_id":"01401626-4fbb-4d21-b18d-cb453de3f951","html_url":"https://github.com/EmmanuelDemey/eslint-plugin-angular","commit_stats":{"total_commits":664,"total_committers":60,"mean_commits":"11.066666666666666","dds":0.5105421686746988,"last_synced_commit":"552dc4a677c1677b040140ded48234931778c78c"},"previous_names":["gillespie59/eslint-plugin-angularjs","gillespie59/eslint-plugin-angular"],"tags_count":67,"template":false,"template_full_name":null,"purl":"pkg:github/EmmanuelDemey/eslint-plugin-angular","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/EmmanuelDemey%2Feslint-plugin-angular","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/EmmanuelDemey%2Feslint-plugin-angular/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/EmmanuelDemey%2Feslint-plugin-angular/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/EmmanuelDemey%2Feslint-plugin-angular/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/EmmanuelDemey","download_url":"https://codeload.github.com/EmmanuelDemey/eslint-plugin-angular/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/EmmanuelDemey%2Feslint-plugin-angular/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29990843,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-02T01:47:34.672Z","status":"online","status_checked_at":"2026-03-02T02:00:07.342Z","response_time":60,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["angularjs","eslint-plugin","javascript"],"created_at":"2024-09-24T13:48:14.255Z","updated_at":"2026-03-02T02:01:42.371Z","avatar_url":"https://github.com/EmmanuelDemey.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# eslint plugin angular [![Npm version](https://img.shields.io/npm/v/eslint-plugin-angular.svg)](https://www.npmjs.com/package/eslint-plugin-angular) [![Npm downloads per month](https://img.shields.io/npm/dm/eslint-plugin-angular.svg)](https://www.npmjs.com/package/eslint-plugin-angular)\n\n\u003e ESLint rules for your angular project with checks for best-practices, conventions or potential errors.\n\n[![.github/workflows/main.yml](https://github.com/EmmanuelDemey/eslint-plugin-angular/actions/workflows/main.yml/badge.svg)](https://github.com/EmmanuelDemey/eslint-plugin-angular/actions/workflows/main.yml)\n[![Greenkeeper badge](https://badges.greenkeeper.io/Gillespie59/eslint-plugin-angular.svg)](https://greenkeeper.io/)\n[![Join the chat at https://gitter.im/Gillespie59/eslint-plugin-angular](https://img.shields.io/gitter/room/nwjs/nw.js.svg)](https://gitter.im/Gillespie59/eslint-plugin-angular?utm_source=badge\u0026utm_medium=badge\u0026utm_campaign=pr-badge\u0026utm_content=badge)\n\n## Summary\n\nThis repository will give access to new rules for the ESLint tool. You should use it only if you are developing an AngularJS application.\n\nSince the 0.0.4 release, some rules defined in [John Papa's Guideline](https://github.com/johnpapa/angular-styleguide/blob/master/a1) have been implemented. In the description below, you will have a link to the corresponding part of the guideline, in order to have more information.\n\n\n\n## Contents\n\n- [Usage with shareable config](#usage-with-shareable-config)\n- [Usage without shareable config](#usage-without-shareable-config)\n- [Development Commands](#development-commands)\n- [Rules](#rules)\n- [Need your help](#need-your-help)\n- [How to create a new rule](#how-to-create-a-new-rule)\n- [Default ESLint configuration file](#default-eslint-configuration-file)\n- [Who uses it?](#who-uses-it)\n- [Team](#team)\n\n\n\n## Usage with [shareable](http://eslint.org/docs/developer-guide/shareable-configs.html) config\n\n1. Install `eslint` as a dev-dependency:\n\n    ```shell\n    npm install --save-dev eslint\n    # or with pnpm\n    pnpm add -D eslint\n    ```\n\n2. Install `eslint-plugin-angular` as a dev-dependency:\n\n    ```shell\n    npm install --save-dev eslint-plugin-angular\n    # or with pnpm\n    pnpm add -D eslint-plugin-angular\n    ```\n\n3. Use the shareable config by adding it to your `eslintrc.config.mjs`:\n\n    ```javascript\n    import angular from \"eslint-plugin-angular\";\n\n    export default defineConfig([{\n      plugins: {\n        angular\n      },\n      rules: {\n        ...angular.configs.johnpapa.rules\n      }\n    }]);\n    ```\n\n\n\n## Usage without shareable config\n\n1. Install `eslint` as a dev-dependency:\n\n    ```shell\n    npm install --save-dev eslint\n    # or with pnpm\n    pnpm add -D eslint\n    ```\n\n2. Install `eslint-plugin-angular` as a dev-dependency:\n\n    ```shell\n    npm install --save-dev eslint-plugin-angular\n    # or with pnpm\n    pnpm add -D eslint-plugin-angular\n    ```\n\n3. Enable the plugin by adding it to your `eslint.config.mjs`:\n\n    ```javascript\n    import angular from \"eslint-plugin-angular\";\n\n    export default defineConfig([{\n      plugins: {\n        angular\n      }\n    }]);\n    ```\n4. You can also configure these rules in your `eslint.config.mjs`. All rules defined in this plugin have to be prefixed by 'angular/'\n\n    ```javascript\n    import angular from \"eslint-plugin-angular\";\n\n    export default defineConfig([{\n      plugins: {\n        angular\n      },\n      rules: {\n        \"angular/controller-name\": \"error\"\n      }\n    }]);\n    ```\n\n----\n\n\n## Development Commands\n\nThis project uses pnpm for package management and npm scripts for all build and development tasks.\n\n### Prerequisites\n\nInstall pnpm globally if not already installed:\n\n```bash\nnpm install -g pnpm\n```\n\nOr use corepack (recommended for Node.js \u003e= 16.13):\n\n```bash\ncorepack enable\ncorepack prepare pnpm@latest --activate\n```\n\n### Available Commands\n\n* **`pnpm run lint`** - Run Oxlint on all JavaScript files\n  * Fast code quality checks using OXC (Rust-based linter)\n  * Checks code quality and style across the entire project\n  * Exit code 0 on success, 1 on lint errors\n\n* **`pnpm run docs`** - Generate documentation\n  * Updates README.md with rule descriptions\n  * Creates individual markdown files in docs/rules/ for each rule\n  * Run this after adding or modifying rules\n\n* **`pnpm run test:run`** - Run test suite with coverage\n  * Executes all 2141+ tests using Mocha\n  * Generates coverage reports (LCOV and text formats)\n  * Coverage reports available in coverage/lcov-report/index.html\n\n* **`pnpm test`** - Run complete build pipeline\n  * Executes lint → docs → test:run sequentially\n  * Stops immediately if any step fails (fail-fast)\n  * This is what CI runs - ensure it passes before committing\n\n### For Contributors\n\nWhen working on the project:\n\n1. Install dependencies: `pnpm install`\n2. Run `pnpm test` before committing to ensure all checks pass\n3. Run `pnpm run docs` after modifying rule documentation\n4. Check `pnpm run lint` if you encounter style issues\n5. Run `pnpm run test:run` to execute tests with coverage\n\n----\n\n\n## Rules\n\nRules in eslint-plugin-angular are divided into several categories to help you better understand their value.\n\n\n### Possible Errors\n\nThe following rules detect patterns that can lead to errors.\n\n * [avoid-scope-typos](docs/rules/avoid-scope-typos.md) - Avoid mistakes when naming methods defined on the scope object\n * [module-getter](docs/rules/module-getter.md) - disallow to reference modules with variables and require to use the getter syntax instead `angular.module('myModule')` ([y022](https://github.com/johnpapa/angular-styleguide/blob/master/a1/README.md#style-y022))\n * [module-setter](docs/rules/module-setter.md) - disallow to assign modules to variables (linked to [module-getter](docs/module-getter.md) ([y021](https://github.com/johnpapa/angular-styleguide/blob/master/a1/README.md#style-y021))\n * [no-private-call](docs/rules/no-private-call.md) - disallow use of internal angular properties prefixed with $$\n\n### Best Practices\n\nThese are rules designed to prevent you from making mistakes. They either prescribe a better way of doing something or help you avoid footguns..\n\n * [component-limit](docs/rules/component-limit.md) - limit the number of angular components per file ([y001](https://github.com/johnpapa/angular-styleguide/blob/master/a1/README.md#style-y001))\n * [controller-as-route](docs/rules/controller-as-route.md) - require the use of controllerAs in routes or states ([y031](https://github.com/johnpapa/angular-styleguide/blob/master/a1/README.md#style-y031))\n * [controller-as-vm](docs/rules/controller-as-vm.md) - require and specify a capture variable for `this` in controllers ([y032](https://github.com/johnpapa/angular-styleguide/blob/master/a1/README.md#style-y032))\n * [controller-as](docs/rules/controller-as.md) - disallow assignments to `$scope` in controllers ([y031](https://github.com/johnpapa/angular-styleguide/blob/master/a1/README.md#style-y031))\n * [deferred](docs/rules/deferred.md) - use `$q(function(resolve, reject){})` instead of `$q.deferred`\n * [di-unused](docs/rules/di-unused.md) - disallow unused DI parameters\n * [directive-restrict](docs/rules/directive-restrict.md) - disallow any other directive restrict than 'A' or 'E' ([y074](https://github.com/johnpapa/angular-styleguide/blob/master/a1/README.md#style-y074))\n * [empty-controller](docs/rules/empty-controller.md) - disallow empty controllers\n * [no-controller](docs/rules/no-controller.md) - disallow use of controllers (according to the component first pattern)\n * [no-inline-template](docs/rules/no-inline-template.md) - disallow the use of inline templates\n * [no-run-logic](docs/rules/no-run-logic.md) - keep run functions clean and simple ([y171](https://github.com/johnpapa/angular-styleguide/blob/master/a1/README.md#style-y171))\n * [no-services](docs/rules/no-services.md) - disallow DI of specified services for other angular components (`$http` for controllers, filters and directives)\n * [on-watch](docs/rules/on-watch.md) - require `$on` and `$watch` deregistration callbacks to be saved in a variable\n * [prefer-component](docs/rules/prefer-component.md) - \n\n### Deprecated Angular Features\n\nThese rules prevent you from using deprecated angular features.\n\n * [no-cookiestore](docs/rules/no-cookiestore.md) - use `$cookies` instead of `$cookieStore`\n * [no-directive-replace](docs/rules/no-directive-replace.md) - disallow the deprecated directive replace property\n * [no-http-callback](docs/rules/no-http-callback.md) - disallow the `$http` methods `success()` and `error()`\n\n### Naming\n\nThese rules help you to specify several naming conventions.\n\n * [component-name](docs/rules/component-name.md) - require and specify a prefix for all component names\n * [constant-name](docs/rules/constant-name.md) - require and specify a prefix for all constant names ([y125](https://github.com/johnpapa/angular-styleguide/blob/master/a1/README.md#style-y125))\n * [controller-name](docs/rules/controller-name.md) - require and specify a prefix for all controller names ([y123](https://github.com/johnpapa/angular-styleguide/blob/master/a1/README.md#style-y123), [y124](https://github.com/johnpapa/angular-styleguide/blob/master/a1/README.md#style-y124))\n * [directive-name](docs/rules/directive-name.md) - require and specify a prefix for all directive names ([y073](https://github.com/johnpapa/angular-styleguide/blob/master/a1/README.md#style-y073), [y126](https://github.com/johnpapa/angular-styleguide/blob/master/a1/README.md#style-y126))\n * [factory-name](docs/rules/factory-name.md) - require and specify a prefix for all factory names ([y125](https://github.com/johnpapa/angular-styleguide/blob/master/a1/README.md#style-y125))\n * [file-name](docs/rules/file-name.md) - require and specify a consistent component name pattern ([y120](https://github.com/johnpapa/angular-styleguide/blob/master/a1/README.md#style-y120), [y121](https://github.com/johnpapa/angular-styleguide/blob/master/a1/README.md#style-y121))\n * [filter-name](docs/rules/filter-name.md) - require and specify a prefix for all filter names\n * [module-name](docs/rules/module-name.md) - require and specify a prefix for all module names ([y127](https://github.com/johnpapa/angular-styleguide/blob/master/a1/README.md#style-y127))\n * [provider-name](docs/rules/provider-name.md) - require and specify a prefix for all provider names ([y125](https://github.com/johnpapa/angular-styleguide/blob/master/a1/README.md#style-y125))\n * [service-name](docs/rules/service-name.md) - require and specify a prefix for all service names ([y125](https://github.com/johnpapa/angular-styleguide/blob/master/a1/README.md#style-y125))\n * [value-name](docs/rules/value-name.md) - require and specify a prefix for all value names ([y125](https://github.com/johnpapa/angular-styleguide/blob/master/a1/README.md#style-y125))\n\n### Conventions\n\nAngular often provide multi ways to to something. These rules help you to define convention for your project.\n\n * [di-order](docs/rules/di-order.md) - require DI parameters to be sorted alphabetically\n * [di](docs/rules/di.md) - require a consistent DI syntax\n * [dumb-inject](docs/rules/dumb-inject.md) - unittest `inject` functions should only consist of assignments from injected values to describe block variables\n * [function-type](docs/rules/function-type.md) - require and specify a consistent function style for components ('named' or 'anonymous') ([y024](https://github.com/johnpapa/angular-styleguide/blob/master/a1/README.md#style-y024))\n * [module-dependency-order](docs/rules/module-dependency-order.md) - require a consistent order of module dependencies\n * [no-service-method](docs/rules/no-service-method.md) - use `factory()` instead of `service()` ([y040](https://github.com/johnpapa/angular-styleguide/blob/master/a1/README.md#style-y040))\n * [one-dependency-per-line](docs/rules/one-dependency-per-line.md) - require all DI parameters to be located in their own line\n * [rest-service](docs/rules/rest-service.md) - disallow different rest service and specify one of '$http', '$resource', 'Restangular'\n * [watchers-execution](docs/rules/watchers-execution.md) - require and specify consistent use `$scope.digest()` or `$scope.apply()`\n\n### Angular Wrappers\n\nThese rules help you to enforce the usage of angular wrappers.\n\n * [angularelement](docs/rules/angularelement.md) - use `angular.element` instead of `$` or `jQuery`\n * [definedundefined](docs/rules/definedundefined.md) - use `angular.isDefined` and `angular.isUndefined` instead of other undefined checks\n * [document-service](docs/rules/document-service.md) - use `$document` instead of `document` ([y180](https://github.com/johnpapa/angular-styleguide/blob/master/a1/README.md#style-y180))\n * [foreach](docs/rules/foreach.md) - use `angular.forEach` instead of native `Array.prototype.forEach`\n * [interval-service](docs/rules/interval-service.md) - use `$interval` instead of `setInterval` ([y181](https://github.com/johnpapa/angular-styleguide/blob/master/a1/README.md#style-y181))\n * [json-functions](docs/rules/json-functions.md) - use `angular.fromJson` and 'angular.toJson' instead of `JSON.parse` and `JSON.stringify`\n * [log](docs/rules/log.md) - use the `$log` service instead of the `console` methods\n * [no-angular-mock](docs/rules/no-angular-mock.md) - require to use `angular.mock` methods directly\n * [no-jquery-angularelement](docs/rules/no-jquery-angularelement.md) - disallow to wrap `angular.element` objects with `jQuery` or `$`\n * [timeout-service](docs/rules/timeout-service.md) - use `$timeout` instead of `setTimeout` ([y181](https://github.com/johnpapa/angular-styleguide/blob/master/a1/README.md#style-y181))\n * [typecheck-array](docs/rules/typecheck-array.md) - use `angular.isArray` instead of `typeof` comparisons\n * [typecheck-date](docs/rules/typecheck-date.md) - use `angular.isDate` instead of `typeof` comparisons\n * [typecheck-function](docs/rules/typecheck-function.md) - use `angular.isFunction` instead of `typeof` comparisons\n * [typecheck-number](docs/rules/typecheck-number.md) - use `angular.isNumber` instead of `typeof` comparisons\n * [typecheck-object](docs/rules/typecheck-object.md) - use `angular.isObject` instead of `typeof` comparisons\n * [typecheck-string](docs/rules/typecheck-string.md) - use `angular.isString` instead of `typeof` comparisons\n * [window-service](docs/rules/window-service.md) - use `$window` instead of `window` ([y180](https://github.com/johnpapa/angular-styleguide/blob/master/a1/README.md#style-y180))\n\n### Misspelling\n\nThese rules help you avoiding misspellings.\n\n * [on-destroy](docs/rules/on-destroy.md) - Check for common misspelling $on('destroy', ...).\n\n\n----\n\n\n## Need your help\n\nIt is an opensource project. Any help will be very useful. You can :\n- Create issue\n- Send Pull Request\n- Write Documentation\n- Add new Features\n- Add new Rules\n- Improve the quality\n- Reply to issues\n\nAll development happens on the `development` branch. This means all pull requests should be made to the `development` branch.\n\nIf it is time to release, @Gillespie59 will bump the version in `package.json`, create a Git tag and merge the `development` branch into `master`. @Gillespie59 will then publish the new release to the npm registry.\n\n\n\n## How to create a new rule\n\nWe appreciate contributions and the following notes will help you before you open a Pull Request.\n\n### Check the issues\n\nHave a look at the existing issues. There may exist similar issues with useful information.\n\n### Read the documentation\n\nThere are some useful references for creating new rules. Specificly useful are:\n\n* [The Context Object](http://eslint.org/docs/developer-guide/working-with-rules#the-context-object) - This is the most basic understanding needed for adding or modifying a rule.\n* [Options Schemas](http://eslint.org/docs/developer-guide/working-with-rules#options-schemas) - This is the preferred way for validating configuration options.\n* [Scope](http://estools.github.io/escope/Scope.html) - This is the scope object returned by `context.getScope()`.\n\n### Files you have to create\n\n* `rules/\u003cyour-rule\u003e.js`\n    * JavaScript file with the new rule\n    * The filename `\u003cyour-rule\u003e` is exactly the usage name in eslint configs `angular/\u003cyour-rule\u003e`\n    * Have a look at the `angularRule` wrapper and the `utils` (both in `rules/utils/`) - they probably make things easier for you\n    * Add a documentation comment to generate a markdown documentation with the `npm run docs` task\n* `test/\u003cyour-rule\u003e.js`\n    * Write some tests and execute them with `npm run test:run`\n    * Have a look at the coverage reports `coverage/lcov-report/index.html`\n* `examples/\u003cyour-rule\u003e.js`\n    * Add some examples for the documentation\n    * Run the `npm run docs` task to test the examples and update the markdown documentation\n* `docs/\u003cyour-rule\u003e.md`\n    * Generated by the `npm run docs` task\n\n### Files you have to touch\n\n* `index.js`\n   * Add your rule `rulesConfiguration.addRule('\u003cyour-rule\u003e', [0, {someConfig: 'someValue'}])`\n\n### Before you open your PR\n\n* Check that the `npm test` task is working\n* Commit generated changes in `README.md` and `docs/\u003cyour-rule\u003e.md`\n* Open your PR to the `development` branch NOT `master`\n\n### Rules specific for Angular 1 or 2\n\nWe can use a property, defined in the ESLint configuration file, in order to know which version is used : Angular 1 or Angular 2. based on this property, you can create rules for each version.\n\n```javascript\nimport angular from \"eslint-plugin-angular\";\n\nexport default defineConfig([\n  {\n    files: [\"**/*.js\"],\n    plugins: {\n      angular\n    },\n    languageOptions: {\n      globals: {\n        angular: true\n      }\n    },\n    settings: {\n      angular: 2\n    },\n    rules: {\n      \"angular/controller-name\": [\"error\", \"/[A-Z].*Controller$/\"]\n    }\n  }\n]);\n```\n\nAnd in your rule, you can access to this property thanks to the `context` object :\n\n```javascript\n//If Angular 2 is used, we disabled the rule\nif(context.settings.angular === 2){\n    return {};\n}\n\nreturn {\n\n    'CallExpression': function(node) {\n    }\n};\n```\n\n\n\n## Default ESLint configuration file\n\nHere is the basic configuration for the rules defined in the ESLint plugin, in order to be compatible with the guideline provided by @johnpapa :\n\n```javascript\nrules: {\n  \"no-use-before-define\": \"off\"\n}\n```\n\n\n\n## Who uses it?\n\n- [argo](https://github.com/albertosantini/argo)\n- [generator-gillespie59-angular](https://github.com/Gillespie59/generator-gillespie59-angular/)\n- [generator-ng-poly](https://github.com/dustinspecker/generator-ng-poly)\n- [JHipster](http://jhipster.github.io/)\n- [generator-gulp-angular](https://github.com/Swiip/generator-gulp-angular)\n\n\n## Team\n\n[![Emmanuel Demey](https://avatars.githubusercontent.com/u/555768?s=117)](http://gillespie59.github.io/) | [![Tilman Potthof](https://avatars.githubusercontent.com/u/157532?s=117)](https://github.com/tilmanpotthof) | [![Remco Haszing](https://avatars.githubusercontent.com/u/779047?s=117)](https://github.com/remcohaszing) |\n:---:|:---:|:---:|\n[Emmanuel Demey](http://gillespie59.github.io/) | [Tilman Potthof](https://github.com/tilmanpotthof) | [Remco Haszing](https://github.com/remcohaszing) |\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Femmanueldemey%2Feslint-plugin-angular","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Femmanueldemey%2Feslint-plugin-angular","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Femmanueldemey%2Feslint-plugin-angular/lists"}