Updated November 2026: rewritten for Angular 22. The package is now simply
angular-eslint, andng addgenerates an ESLint flat config (eslint.config.js) instead of.eslintrc.json, so I explain that new file below.
ESLint is a static code analyzer (a linter): it finds problems in JavaScript and TypeScript code that break the configured rules, and fixes many of them. Angular used to ship another linter, TSLint, which was deprecated in 2019 in favour of ESLint's TypeScript support. Angular removed TSLint in version 12.
In this article, we add ESLint to an Angular 22 project. It is the second article of a series that starts with Configure Prettier with Angular.
Prerequisites
- Node.js: Angular 22 requires
^22.22.3,^24.15.0or^26.0.0(see Version compatibility). - Angular CLI:
npm install -g @angular/cli. - An editor. I use Visual Studio Code.
Create an Angular project
Create a project as in the previous article (CSS, no SSR, no AI tools):
ng new angular-eslint
cd angular-eslintA new Angular project still has no linter (it has a Prettier configuration, though).
Install ESLint
Add angular-eslint with the Angular CLI:
ng add angular-eslintNote: In the first version of this article, the command was
ng add @angular-eslint/schematics. Today, the singleangular-eslintpackage brings the builder, the schematics, the ESLint plugins and the template parser together.
The CLI asks you to confirm the installation. It then installs the dependencies, detects a single project without a linter and wires everything up:
✔ Determining Package Manager
› Found compatible package version: 22.6.0.
✔ Installing package
angular-eslint v22 matches this workspace's Angular v22.
...
We detected that you have a single project in your workspace and no existing linter wired up, so we are configuring ESLint for you automatically.
...
CREATE eslint.config.js (1004 bytes)
UPDATE package.json (934 bytes)
UPDATE angular.json (2211 bytes)
√ Packages installed successfully.Here is what changed:
- package.json: a
"lint": "ng lint"script and four devDependencies:angular-eslint(22, for Angular 22),eslint,@eslint/jsandtypescript-eslint. - angular.json: a
linttarget that runs the@angular-eslint/builder:lintbuilder onsrc/**/*.tsandsrc/**/*.html. That is what makesng lintwork. - eslint.config.js: the ESLint configuration.
The eslint.config.js file
Since ESLint 9, the default format is the flat config: one JavaScript file, eslint.config.js, that exports an array of configuration objects. It replaces the .eslintrc.json file of the first version of this article. Here is the file ng add generates:
// @ts-check
const eslint = require('@eslint/js');
const { defineConfig } = require('eslint/config');
const tseslint = require('typescript-eslint');
const angular = require('angular-eslint');
module.exports = defineConfig([
{
files: ['**/*.ts'],
extends: [
eslint.configs.recommended,
tseslint.configs.recommended,
tseslint.configs.stylistic,
angular.configs.tsRecommended,
],
processor: angular.processInlineTemplates,
rules: {
'@angular-eslint/directive-selector': [
'error',
{
type: 'attribute',
prefix: 'app',
style: 'camelCase',
},
],
'@angular-eslint/component-selector': [
'error',
{
type: 'element',
prefix: 'app',
style: 'kebab-case',
},
],
},
},
{
files: ['**/*.html'],
extends: [angular.configs.templateRecommended, angular.configs.templateAccessibility],
rules: {},
},
]);Let's read it:
// @ts-checkanddefineConfig(...): the editor type-checks the configuration, so a typo in an option is underlined.- The first object applies to the TypeScript files (
files: ['**/*.ts']):extendsstacks the recommended rules of ESLint (@eslint/js), of typescript-eslint (recommendedandstylistic) and of Angular (tsRecommended).processor: angular.processInlineTemplatesextracts inline templates (template: '...'in a component) so they are linted like.htmlfiles.rulessets the selector conventions: components areapp-somethingelements and directives areappSomethingattributes. Theappprefix is theprefixof the project in angular.json.
- The second object applies to the templates (
files: ['**/*.html']): the recommended template rules and the accessibility rules (an<img>withoutalt, aclickwithout a keyboard event…).
To add or change a rule, add it to the rules of the right object, for example '@typescript-eslint/no-explicit-any': 'off'.
Analyze files
Run ESLint on the project:
$ ng lint
Linting "angular-eslint"...
All files pass linting.Templates are analyzed too. For example, if I add <img src="favicon.ico" /> at the end of app.html, the accessibility rules catch it:
Linting "angular-eslint"...
~/angular-eslint/src/app/app.html
354:1 error <img/> element must have a text alternative @angular-eslint/template/alt-text
✖ 1 problem (1 error, 0 warnings)
Lint errors found in the listed files.Fix files
Many rules can fix the code themselves with ng lint --fix. Let's add a small method to app.ts:
export class App {
protected readonly title = signal('angular-eslint');
protected sayHello(): string {
let hello = 'Hello';
return `${hello}, ${this.title()}!`;
}
}ng lint reports a prefer-const error that it can fix:
Linting "angular-eslint"...
~/angular-eslint/src/app/app.ts
14:9 error 'hello' is never reassigned. Use 'const' instead prefer-const
✖ 1 problem (1 error, 0 warnings)
1 error and 0 warnings potentially fixable with the `--fix` option.
Lint errors found in the listed files.ng lint --fix then reports "All files pass linting." and replaces let with const:
- let hello = 'Hello';
+ const hello = 'Hello';VS Code extension
The ESLint extension (dbaeumer.vscode-eslint) shows the problems directly in the editor. Install it from the Extensions view (Ctrl+Shift+X on Windows and Linux, Cmd+Shift+X on macOS): it detects eslint.config.js automatically.
To recommend it to everyone who opens the project, add it to the .vscode/extensions.json file generated by the CLI:
{
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=827846
"recommendations": ["angular.ng-template", "dbaeumer.vscode-eslint"]
}Conclusion
In this article, we added ESLint to an Angular project with ng add angular-eslint, read the generated eslint.config.js, analyzed the code with ng lint and fixed it with ng lint --fix.
To run ESLint and Prettier automatically before each commit, read the last article of the series: Configure Husky with Angular.
Source code of the article: GitHub source code
References
- angular-eslint — the Angular builder, schematics, plugins and template parser for ESLint.
- ESLint: Configuration files — the flat config format,
files,extendsandrules. - ESLint: Configuration migration guide — moving from
.eslintrctoeslint.config.js. - ESLint: prefer-const — the rule fixed in this article.
- typescript-eslint: Getting started — the TypeScript parser and the
recommendedandstylisticconfigs. - Angular CLI: ng lint — the
lintcommand and its options. - Angular: Version compatibility — the Node.js versions Angular 22 supports.
- VS Code: Workspace recommended extensions —
.vscode/extensions.json. - ESLint extension for VS Code — the editor integration.
- TSLint in 2019 — the deprecation announcement of TSLint.