Modern ESLint configuration with strict rules for Angular development
A production-ready, opinionated ESLint configuration that enforces best practices for Angular applications. Combines rules from industry-leading plugins into a single package with zero additional configuration required.
📘 TypeScript: Promise-async, type imports, strict typing, type safety, extraneous classes,...
✨ Code Quality: Complexity max, file length control, import cycles detection, 100+ Unicorn best practices,...
🎨 Style: Airbnb extended, max line length, object/class newlines, sorted classes/imports/objects/types,...
📁 Naming: File/folder/class suffix conventions enforced (components, services, pipes, interfaces,...)
🔍 Templates: 30+ rules with alphabetical attrs, complexity max, control flow, trackBy, a11y, no-any,...
- 🎩 Airbnb Extended - Airbnb style guide
🅰️ Angular ESLint - Angular-specific rules- ⚙️ ESLint - Core linting engine
- 📦 Import-X - Import/export validation and cycle detection
- 💅 Perfectionist - Take Your Code to a Beauty Salon
- 🎨 Stylistic - Code formatting rules
- 📘 TypeScript ESLint - TypeScript linting
- 🦄 Unicorn - More than 100 powerful ESLint rules
yarn add eslint-config-angular-strict --dev
⚠️ Important: Remove any existingeslintdependency from your project - it's included!
Create an eslint.config.js file (flat config format):
import angularStrict from 'eslint-config-angular-strict';
export default [
...angularStrict,
// Your custom overrides here
];Add the following to your package.json:
Make sure your tsconfig.json is properly configured:
{
"compilerOptions": {
// ...
"allowUnreachableCode": false,
"allowUnusedLabels": false,
"exactOptionalPropertyTypes": true,
"noImplicitOverride": true,
"noUncheckedIndexedAccess": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"target": "esnext",
},
"angularCompilerOptions": {
// ...
"extendedDiagnostics": { "defaultCategory": "error" },
"strictInjectionParameters": true,
"strictStandalone": true,
"strictTemplates": true,
},
}ℹ️ Note:
target: "esnext"auto-includes the latest standard lib (esnext + DOM), which several Unicorn rules require. Without it, some rules may suggest APIs that TypeScript doesn't recognize as built-in. No need to setlibexplicitly — TypeScript infers it fromtarget.
This config handles TypeScript formatting via ESLint. Prettier should only be used for HTML templates.
{
"printWidth": 165,
"singleQuote": true,
"overrides": [
{
"files": "*.html",
"options": { "parser": "angular" }
}
]
}{
"scripts": {
// ...
"lint": "ng lint && prettier --check \"src/**/*.html\"",
"lint:fix": "ng lint --fix && prettier --write \"src/**/*.html\"",
},
}
⚠️ Important: Only target*.htmlfiles with Prettier. Running Prettier on.tsfiles will conflict with ESLint Stylistic rules.
{
// ...
"[html]": { "editor.defaultFormatter": "esbenp.prettier-vscode" },
"editor.defaultFormatter": "dbaeumer.vscode-eslint",
"editor.formatOnSave": true,
"editor.formatOnType": true,
"eslint.format.enable": true,
"eslint.validate": [, /*...*/ "html", "typescript"],
}This ensures ESLint handles .ts formatting on save, while Prettier handles .html templates.
Contributions are welcome! Please open an issue or submit a PR.
MIT © Jean-benoit Gautier
{ // ... "type": "module", }