# @angular-eslint/eslint-plugin

> ESLint plugin for Angular applications, following https://angular.dev/style-guide

Latest version **22.5.0** (published 2026-09-07) · MIT license · 3.2M weekly downloads

## Install

```sh
npm install @angular-eslint/eslint-plugin
pnpm add @angular-eslint/eslint-plugin
yarn add @angular-eslint/eslint-plugin
bun add @angular-eslint/eslint-plugin
```

## Health

**Score 85/100 (A)** — status: active.

Positive: high downloads; has types; no vulnerabilities; has provenance; recently updated; high maintenance score.

Warnings: no esm support.

## Facts

| | |
|---|---|
| Version | 22.5.0 |
| Published | 2026-09-07 |
| First published | 2019-07-29 |
| Weekly downloads | 3.2M |
| License | MIT |
| TypeScript types | bundled |
| Module format | CommonJS |
| Dependencies | 3 |
| Unpacked size | 326.2 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| Provenance | attested (GitHub Actions) |
| GitHub stars | 1784 |
| Maintainers | jameshenry |

## Links

- npm: https://www.npmjs.com/package/@angular-eslint/eslint-plugin
- Repository: https://github.com/angular-eslint/angular-eslint
- Issues: https://github.com/angular-eslint/angular-eslint/issues
- npm.io page: https://npm.io/package/@angular-eslint/eslint-plugin

## Dependencies (3)

- [ts-api-utils](https://npm.io/package/ts-api-utils.md) ^2.1.0
- [@angular-eslint/utils](https://npm.io/package/@angular-eslint/utils.md) 22.5.0
- [@angular-eslint/bundled-angular-compiler](https://npm.io/package/@angular-eslint/bundled-angular-compiler.md) 22.5.0

## Recent versions

- 22.5.0 (latest) — 2026-09-07
- 22.5.1-alpha.6 (canary) — 2026-09-17
- 19.8.1 (previous) — 2025-06-19
- 20.0.0-beta.1 (prerelease-v20) — 2025-06-02
- 19.4.1-pr-2451-1 (prerelease-v19) — 2025-05-25
- 18.0.0-alpha.16 (rc-v18) — 2024-05-28
- 17.0.0-alpha.0 (next) — 2023-11-06
- 4.3.1 (patch) — 2021-11-18
- 4.2.0-tmp.0 (tmp) — 2021-04-28
- 22.5.1-alpha.5 — 2026-09-17
- 22.5.1-alpha.4 — 2026-09-14
- 22.5.1-alpha.3 — 2026-09-13
- 22.5.1-alpha.2 — 2026-09-13
- 22.5.1-alpha.1 — 2026-09-08
- 22.5.1-alpha.0 — 2026-09-07
- … 1232 more at https://npm.io/package/@angular-eslint/eslint-plugin/versions

## README

# @angular-eslint/eslint-plugin

Please see https://github.com/angular-eslint/angular-eslint for full usage instructions and guidance.

## Premade configs

The premade flat configs that combine these rules are provided by the umbrella [`angular-eslint`](https://github.com/angular-eslint/angular-eslint/blob/main/packages/angular-eslint/src/configs/README.md) package.

## Rules

<!-- begin problems rule list -->

### Possible problems

**Key**

- :white_check_mark: = recommended
- :wrench: = fixable
- :bulb: = has suggestions

<!-- prettier-ignore-start -->
| Rule | Description | :white_check_mark: | :wrench: | :bulb: |
| --- | --- | --- | --- | --- |
| [`computed-must-return`](https://github.com/angular-eslint/angular-eslint/blob/main/packages/eslint-plugin/docs/rules/computed-must-return.md) | Ensures that computed() returns a value. Omitting the value is likely a mistake. |  |  |  |
| [`contextual-lifecycle`](https://github.com/angular-eslint/angular-eslint/blob/main/packages/eslint-plugin/docs/rules/contextual-lifecycle.md) | Ensures that lifecycle methods are used in a correct context | :white_check_mark: |  |  |
| [`inject-at-top`](https://github.com/angular-eslint/angular-eslint/blob/main/packages/eslint-plugin/docs/rules/inject-at-top.md) | Requires inject() calls to be declared at the top of the class, before any other member |  |  |  |
| [`no-async-lifecycle-method`](https://github.com/angular-eslint/angular-eslint/blob/main/packages/eslint-plugin/docs/rules/no-async-lifecycle-method.md) | Angular Lifecycle methods should not be async. Angular does not wait for async lifecycle but the code incorrectly suggests it does. |  |  |  |
| [`no-attribute-decorator`](https://github.com/angular-eslint/angular-eslint/blob/main/packages/eslint-plugin/docs/rules/no-attribute-decorator.md) | The @Attribute decorator is used to obtain a single value for an attribute. This is a much less common use case than getting a stream of values (using @Input), so the @Attribute decorator is often mistakenly used when @Input is intended. This rule disallows the usage of @Attribute decorator entirely to prevent these mistakes. |  |  |  |
| [`no-developer-preview`](https://github.com/angular-eslint/angular-eslint/blob/main/packages/eslint-plugin/docs/rules/no-developer-preview.md) | Disallow using code which is marked as developer preview |  |  |  |
| [`no-experimental`](https://github.com/angular-eslint/angular-eslint/blob/main/packages/eslint-plugin/docs/rules/no-experimental.md) | Disallow using code which is marked as experimental |  |  |  |
| [`no-implicit-take-until-destroyed`](https://github.com/angular-eslint/angular-eslint/blob/main/packages/eslint-plugin/docs/rules/no-implicit-take-until-destroyed.md) | Ensures that `takeUntilDestroyed()` is called with an explicit `DestroyRef` when used outside of an injection context |  |  |  |
| [`reactive-context-must-read-signal`](https://github.com/angular-eslint/angular-eslint/blob/main/packages/eslint-plugin/docs/rules/reactive-context-must-read-signal.md) | Ensures that reactive contexts such as computed(), linkedSignal() and effect() read at least one reactive value (a signal). A reactive context with no reactive dependencies never re-runs, which is almost always a mistake. |  |  |  |
| [`require-lifecycle-on-prototype`](https://github.com/angular-eslint/angular-eslint/blob/main/packages/eslint-plugin/docs/rules/require-lifecycle-on-prototype.md) | Ensures that lifecycle methods are defined on the object's prototype instead of on an instance. |  |  |  |
| [`sort-lifecycle-methods`](https://github.com/angular-eslint/angular-eslint/blob/main/packages/eslint-plugin/docs/rules/sort-lifecycle-methods.md) | Ensures that lifecycle methods are declared in order of execution |  |  |  |
<!-- prettier-ignore-end -->

<!-- end problems rule list -->

<!-- begin suggestions rule list -->

### Suggestions

**Key**

- :white_check_mark: = recommended
- :wrench: = fixable
- :bulb: = has suggestions

<!-- prettier-ignore-start -->
| Rule | Description | :white_check_mark: | :wrench: | :bulb: |
| --- | --- | --- | --- | --- |
| [`component-class-suffix`](https://github.com/angular-eslint/angular-eslint/blob/main/packages/eslint-plugin/docs/rules/component-class-suffix.md) | Classes decorated with @Component must have suffix "Component" (or custom) in their name. Note: As of v20, this is no longer recommended by the Angular Team. |  |  |  |
| [`component-max-inline-declarations`](https://github.com/angular-eslint/angular-eslint/blob/main/packages/eslint-plugin/docs/rules/component-max-inline-declarations.md) | Enforces a maximum number of lines in inline template, styles and animations. |  |  |  |
| [`component-selector`](https://github.com/angular-eslint/angular-eslint/blob/main/packages/eslint-plugin/docs/rules/component-selector.md) | Component selectors should follow given naming rules. See more at https://angular.dev/style-guide#choosing-component-selectors. |  |  |  |
| [`consistent-component-styles`](https://github.com/angular-eslint/angular-eslint/blob/main/packages/eslint-plugin/docs/rules/consistent-component-styles.md) | Ensures consistent usage of `styles`/`styleUrls`/`styleUrl` within Component metadata |  | :wrench: |  |
| [`contextual-decorator`](https://github.com/angular-eslint/angular-eslint/blob/main/packages/eslint-plugin/docs/rules/contextual-decorator.md) | Ensures that classes use contextual decorators in their body |  |  |  |
| [`directive-class-suffix`](https://github.com/angular-eslint/angular-eslint/blob/main/packages/eslint-plugin/docs/rules/directive-class-suffix.md) | Classes decorated with @Directive must have suffix "Directive" (or custom) in their name. Note: As of v20, this is no longer recommended by the Angular Team. |  |  |  |
| [`directive-selector`](https://github.com/angular-eslint/angular-eslint/blob/main/packages/eslint-plugin/docs/rules/directive-selector.md) | Directive selectors should follow given naming rules. See more at https://angular.dev/style-guide#choosing-directive-selectors. |  |  |  |
| [`no-duplicates-in-metadata-arrays`](https://github.com/angular-eslint/angular-eslint/blob/main/packages/eslint-plugin/docs/rules/no-duplicates-in-metadata-arrays.md) | Ensures that metadata arrays do not contain duplicate entries. |  |  |  |
| [`no-empty-lifecycle-method`](https://github.com/angular-eslint/angular-eslint/blob/main/packages/eslint-plugin/docs/rules/no-empty-lifecycle-method.md) | Disallows declaring empty lifecycle methods | :white_check_mark: |  | :bulb: |
| [`no-forward-ref`](https://github.com/angular-eslint/angular-eslint/blob/main/packages/eslint-plugin/docs/rules/no-forward-ref.md) | Disallows usage of `forwardRef` references for DI |  |  |  |
| [`no-input-prefix`](https://github.com/angular-eslint/angular-eslint/blob/main/packages/eslint-plugin/docs/rules/no-input-prefix.md) | Ensures that input bindings, including aliases, are not named or prefixed by the configured disallowed prefixes |  |  |  |
| [`no-input-rename`](https://github.com/angular-eslint/angular-eslint/blob/main/packages/eslint-plugin/docs/rules/no-input-rename.md) | Ensures that input bindings are not aliased | :white_check_mark: | :wrench: | :bulb: |
| [`no-inputs-metadata-property`](https://github.com/angular-eslint/angular-eslint/blob/main/packages/eslint-plugin/docs/rules/no-inputs-metadata-property.md) | Disallows usage of the `inputs` metadata property | :white_check_mark: |  |  |
| [`no-lifecycle-call`](https://github.com/angular-eslint/angular-eslint/blob/main/packages/eslint-plugin/docs/rules/no-lifecycle-call.md) | Disallows explicit calls to lifecycle methods |  |  |  |
| [`no-output-native`](https://github.com/angular-eslint/angular-eslint/blob/main/packages/eslint-plugin/docs/rules/no-output-native.md) | Ensures that output bindings, including aliases, are not named as standard DOM events | :white_check_mark: |  |  |
| [`no-output-on-prefix`](https://github.com/angular-eslint/angular-eslint/blob/main/packages/eslint-plugin/docs/rules/no-output-on-prefix.md) | Ensures that output bindings, including aliases, are not named "on", nor prefixed with it. See more at https://angular.dev/guide/components/outputs#choosing-event-names | :white_check_mark: |  |  |
| [`no-output-rename`](https://github.com/angular-eslint/angular-eslint/blob/main/packages/eslint-plugin/docs/rules/no-output-rename.md) | Ensures that output bindings are not aliased | :white_check_mark: | :wrench: | :bulb: |
| [`no-outputs-metadata-property`](https://github.com/angular-eslint/angular-eslint/blob/main/packages/eslint-plugin/docs/rules/no-outputs-metadata-property.md) | Disallows usage of the `outputs` metadata property | :white_check_mark: |  |  |
| [`no-pipe-impure`](https://github.com/angular-eslint/angular-eslint/blob/main/packages/eslint-plugin/docs/rules/no-pipe-impure.md) | Disallows the declaration of impure pipes |  |  | :bulb: |
| [`no-queries-metadata-property`](https://github.com/angular-eslint/angular-eslint/blob/main/packages/eslint-plugin/docs/rules/no-queries-metadata-property.md) | Disallows usage of the `queries` metadata property. |  |  |  |
| [`no-uncalled-signals`](https://github.com/angular-eslint/angular-eslint/blob/main/packages/eslint-plugin/docs/rules/no-uncalled-signals.md) | Warns user about unintentionally doing logic on the signal, rather than the signal's value |  |  | :bulb: |
| [`pipe-prefix`](https://github.com/angular-eslint/angular-eslint/blob/main/packages/eslint-plugin/docs/rules/pipe-prefix.md) | Enforce consistent prefix for pipes. |  |  |  |
| [`prefer-host-metadata-property`](https://github.com/angular-eslint/angular-eslint/blob/main/packages/eslint-plugin/docs/rules/prefer-host-metadata-property.md) | Use `host` metadata property instead of `@HostBinding` and `HostListener` |  |  |  |
| [`prefer-inject`](https://github.com/angular-eslint/angular-eslint/blob/main/packages/eslint-plugin/docs/rules/prefer-inject.md) | Prefer using the inject() function over constructor parameter injection | :white_check_mark: |  |  |
| [`prefer-on-push-component-change-detection`](https://github.com/angular-eslint/angular-eslint/blob/main/packages/eslint-plugin/docs/rules/prefer-on-push-component-change-detection.md) | Ensures components do not opt out of the default `ChangeDetectionStrategy.OnPush` change detection strategy | :white_check_mark: | :wrench: | :bulb: |
| [`prefer-output-emitter-ref`](https://github.com/angular-eslint/angular-eslint/blob/main/packages/eslint-plugin/docs/rules/prefer-output-emitter-ref.md) | Use `OutputEmitterRef` instead of `@Output()` |  |  |  |
| [`prefer-output-readonly`](https://github.com/angular-eslint/angular-eslint/blob/main/packages/eslint-plugin/docs/rules/prefer-output-readonly.md) | Prefer to declare `@Output`, `OutputEmitterRef` and `OutputRef` as `readonly` since they are not supposed to be reassigned |  |  | :bulb: |
| [`prefer-service-decorator`](https://github.com/angular-eslint/angular-eslint/blob/main/packages/eslint-plugin/docs/rules/prefer-service-decorator.md) | Prefer the `@Service()` decorator over `@Injectable({ providedIn: 'root' })` |  | :wrench: |  |
| [`prefer-signal-model`](https://github.com/angular-eslint/angular-eslint/blob/main/packages/eslint-plugin/docs/rules/prefer-signal-model.md) | Use `model` instead of `input` and `output` for two-way bindings |  | :wrench: |  |
| [`prefer-signals`](https://github.com/angular-eslint/angular-eslint/blob/main/packages/eslint-plugin/docs/rules/prefer-signals.md) | Use readonly signals instead of `@Input()`, `@ViewChild()` and other legacy decorators |  | :wrench: |  |
| [`prefer-standalone`](https://github.com/angular-eslint/angular-eslint/blob/main/packages/eslint-plugin/docs/rules/prefer-standalone.md) | Ensures Components, Directives and Pipes do not opt out of standalone. | :white_check_mark: |  | :bulb: |
| [`relative-url-prefix`](https://github.com/angular-eslint/angular-eslint/blob/main/packages/eslint-plugin/docs/rules/relative-url-prefix.md) | The ./ and ../ prefix is standard syntax for relative URLs; don't depend on Angular's current ability to do without that prefix. |  |  |  |
| [`require-localize-metadata`](https://github.com/angular-eslint/angular-eslint/blob/main/packages/eslint-plugin/docs/rules/require-localize-metadata.md) | Ensures that $localize tagged messages contain helpful metadata to aid with translations. |  |  |  |
| [`runtime-localize`](https://github.com/angular-eslint/angular-eslint/blob/main/packages/eslint-plugin/docs/rules/runtime-localize.md) | Ensures that $localize tagged messages can use runtime-loaded translations. |  |  |  |
| [`sort-keys-in-type-decorator`](https://github.com/angular-eslint/angular-eslint/blob/main/packages/eslint-plugin/docs/rules/sort-keys-in-type-decorator.md) | Ensures that keys in type decorators (Component, Directive, Injectable, NgModule, Pipe) are sorted in a consistent order |  | :wrench: |  |
| [`use-component-selector`](https://github.com/angular-eslint/angular-eslint/blob/main/packages/eslint-plugin/docs/rules/use-component-selector.md) | Component selector must be declared |  |  |  |
| [`use-component-view-encapsulation`](https://github.com/angular-eslint/angular-eslint/blob/main/packages/eslint-plugin/docs/rules/use-component-view-encapsulation.md) | Disallows using `ViewEncapsulation.None` |  |  | :bulb: |
| [`use-injectable-provided-in`](https://github.com/angular-eslint/angular-eslint/blob/main/packages/eslint-plugin/docs/rules/use-injectable-provided-in.md) | Using the `providedIn` property makes `Injectables` tree-shakable |  |  | :bulb: |
| [`use-lifecycle-interface`](https://github.com/angular-eslint/angular-eslint/blob/main/packages/eslint-plugin/docs/rules/use-lifecycle-interface.md) | Ensures that classes implement lifecycle interfaces corresponding to the declared lifecycle methods. See more at https://angular.dev/style-guide#use-lifecycle-hook-interfaces |  | :wrench: |  |
| [`use-pipe-transform-interface`](https://github.com/angular-eslint/angular-eslint/blob/main/packages/eslint-plugin/docs/rules/use-pipe-transform-interface.md) | Ensures that `Pipes` implement `PipeTransform` interface | :white_check_mark: | :wrench: |  |
<!-- prettier-ignore-end -->

<!-- end suggestions rule list -->

<!-- begin layout rule list -->

<!-- end layout rule list -->

<!-- begin deprecated rule list -->

<!-- end deprecated rule list -->

---
_Source: https://npm.io/package/@angular-eslint/eslint-plugin · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
