How to configure Angular linting
Maintaining code quality across a large-scale project is a significant challenge that every professional developer faces.
With over 25 years of experience in software development and as the creator of CoreUI, I’ve personally managed dozens of repositories where strict linting was the only thing preventing architectural decay.
In modern Angular development, the standard and most efficient way to handle this is by migrating from the deprecated TSLint to ESLint using the @angular-eslint suite.
This setup ensures that your TypeScript code and HTML templates follow industry-standard best practices and remains consistent across your entire team.
Use the Angular CLI to add the official ESLint schematics which automatically configures your workspace and converts existing rules.
ng add @angular-eslint/schematics
This command performs several critical tasks: it installs the necessary npm packages, creates a root .eslintrc.json file, and updates your angular.json configuration to include a lint target.
1. Initializing ESLint in an Existing Workspace
When you run the schematics, Angular sets up a “pluggable” architecture. This means your linting rules are not hardcoded but are part of a flexible system that can be extended based on your project requirements.
// Example output of the automated configuration in angular.json
{
"projects": {
"my-app": {
"architect": {
"lint": {
"builder": "@angular-eslint/builder:lint",
"options": {
"lintFilePatterns": [
"src/**/*.ts",
"src/**/*.html"
]
}
}
}
}
}
}
This configuration tells the Angular CLI that whenever you run ng lint, it should use the @angular-eslint builder to scan your TypeScript and HTML files. This is the same foundation we use to maintain the Angular Dashboard Template, ensuring every component meets enterprise standards.
2. Configuring the Root .eslintrc.json
The .eslintrc.json file is where the magic happens. It defines which plugins to use and how rules should be applied to different file types. Most Angular projects use a multi-layered approach where rules are split between TypeScript and HTML files.
{
"root": true,
"ignorePatterns": ["projects/**/*"],
"overrides": [
{
"files": ["*.ts"],
"parserOptions": {
"project": ["tsconfig.json"]
},
"extends": [
"plugin:@angular-eslint/recommended",
"plugin:@angular-eslint/template/process-inline-templates"
],
"rules": {
"@angular-eslint/directive-selector": [
"error", { "type": "attribute", "prefix": "app", "style": "camelCase" }
],
"@angular-eslint/component-selector": [
"error", { "type": "element", "prefix": "app", "style": "kebab-case" }
]
}
}
]
}
In this section, we define how selectors should behave. This ensures that all components and directives strictly follow your team’s naming conventions, preventing collisions with standard HTML elements.
3. Customizing TypeScript Linting Rules
While the recommended defaults are excellent, you often need to tighten or loosen specific rules for your production environment. For instance, you might want to enforce strict typing or forbid the use of console.log in production code.
{
"files": ["*.ts"],
"rules": {
"no-console": "error",
"no-debugger": "error",
"@typescript-eslint/no-explicit-any": "warn",
"@typescript-eslint/consistent-type-definitions": ["error", "interface"],
"@typescript-eslint/no-unused-vars": ["error", { "argsIgnorePattern": "^_" }],
"@angular-eslint/no-empty-lifecycle-method": "error",
"@angular-eslint/use-lifecycle-interface": "error",
"quotes": ["error", "single"],
"semi": ["error", "always"]
}
}
By adding these rules, you force the developer to clean up their code before it reaches the review stage. The no-explicit-any rule is particularly helpful for catching lazy typing, while quotes and semi maintain visual consistency throughout the codebase.
4. Linting Angular HTML Templates
One of the most powerful features of @angular-eslint is its ability to lint HTML templates. This allows you to catch accessibility issues, incorrect data-binding syntax, or structural errors that would otherwise only appear at runtime.
{
"files": ["*.html"],
"extends": [
"plugin:@angular-eslint/template/recommended"
],
"rules": {
"@angular-eslint/template/no-any": "error",
"@angular-eslint/template/attributes-order": "warn",
"@angular-eslint/template/conditional-complexity": ["error", { "maxComplexity": 3 }],
"@angular-eslint/template/no-distracting-elements": "error",
"@angular-eslint/template/use-track-by-iterables": "warn"
}
}
Enforcing use-track-by-iterables ensures that your *ngFor loops are performant, which is critical for large datasets. Similarly, setting a maxComplexity for conditionals prevents your templates from becoming unreadable logic puzzles.
5. Running and Auto-Fixing Code
Once configured, you need a way to execute these checks. The Angular CLI provides a straightforward command to run the linter, but knowing the flags for automatic fixing can save your team hours of manual formatting work.
# Run linting for the default project
ng lint
# Run linting and automatically fix simple errors like quotes or semi-colons
ng lint --fix
# Run linting for a specific project in a monorepo
ng lint my-shared-library
# Output linting results to a specific file format for CI/CD reporting
ng lint --format json --output-file lint-results.json
The --fix flag is your best friend. It resolves about 80% of style-related issues instantly. For the remaining 20%, the linter provides clear descriptions and line numbers in the terminal, guiding you directly to the problem.
6. Integrating with VS Code
To get the most out of your linting configuration, you should enable real-time feedback in your editor. This prevents the “red terminal” frustration by highlighting errors as you type.
// .vscode/settings.json
{
"eslint.validate": [
"javascript",
"javascriptreact",
"typescript",
"typescriptreact",
"html"
],
"editor.codeActionsOnSave": {
"source.fixAll.eslint": "explicit"
},
"eslint.options": {
"extensions": [".ts", ".html"]
}
}
With these settings, VS Code will automatically run the ESLint “fix” command every time you save a file. This creates a seamless development experience where code is formatted correctly without any manual intervention from the developer.
Best Practice Note:
We use this exact configuration in our Free Angular Admin Template to guarantee that the code remains clean and maintainable for thousands of users. Always include linting as a mandatory step in your CI/CD pipeline; if the linter fails, the build should fail. This prevents “broken” code styles from ever reaching your main branch, preserving the technical integrity of your application over the long term.



