ESLint rules for Angular zoneless.
Checks that a zoneless application does not use zone.js-based features and that signals/resources patterns are used, for example:
- no zone.js import and provider
- no zone.js testing functions like
fakeAsync() - no
NgZone - no public or protected writable properties in components
- no
ChangeDectectionStrategy.Eager - no
@Input()and other decorators, to enforceinput()and other signal equivalents - no
ngOnInit()and other component lifecycle methods, to enforce using signals and resources patterns
A blog post on Dev.to explains the context and the purpose of this tool in more details.
Note
Find this tool useful? I’m open to freelance & full-time opportunities. Feel free to reach out on LinkedIn or Bluesky.
- TypeScript ESLint v8
- New flat ESLint configuration (
eslint.config.jsor equivalent)
Note
.eslintrc.json and other legacy ESLint configurations are not supported
- Installation
npm install angular-eslint-zoneless --save-dev- ESLint flat configuration (
eslint.config.jsor equivalent)
const eslint = require("@eslint/js");
const { defineConfig } = require("eslint/config");
const tsEslint = require("typescript-eslint");
const angularEslintZoneless = require("angular-eslint-zoneless"); // ⬅️ add this
module.exports = defineConfig({
files: ["**/*.ts"],
languageOptions: {
parserOptions: {
projectService: true,
},
},
extends: [
eslint.configs.recommended,
tsEslint.configs.strictTypeChecked,
tsEslint.configs.stylisticTypeChecked,
angularEslintZoneless.configs.recommended, // ⬅️ add this (or one of the other presets below)
],
rules: {},
});npm run lint
Note
In VS Code, it may be required to restart for the ESLint extension to apply the new rules.
There are 3 presets available:
minimal: restrict what really does not work without zone.jsrecommended:minimal+ enforce signals patternsstrict:recommended+ go even further in signals patterns
Tip
Use the recommended or strict presets for new projects and projects already fully migrated to zoneless and signals patterns. Use the minimal preset for projects with signals migration still ongoing, and enable the other rules gradually.
| Rule & documentation | in minimal | in recommended | in strict |
|---|---|---|---|
| no-zonejs-import | ✅ | ✅ | ✅ |
| no-providezonechangedetection | ✅ | ✅ | ✅ |
| no-ngzone | ✅ | ✅ | ✅ |
| no-ngzone-testing | ✅ | ✅ | ✅ |
| no-zonejs-testing-functions | ✅ | ✅ | ✅ |
| no-directive-writable-property | ❌ | ✅ | ✅ |
| no-directive-accessor | ❌ | ✅ | ✅ |
| no-eager-change-detection | ❌ | ✅ | ✅ |
| no-ngoninit | ❌ | ✅ | ✅ |
| no-ngdocheck | ❌ | ✅ | ✅ |
| no-ngonchanges | ❌ | ✅ | ✅ |
| no-ngcontentviewinit | ❌ | ✅ | ✅ |
| no-ngcontentviewchecked | ❌ | ✅ | ✅ |
| no-ngafterviewinit | ❌ | ✅ | ✅ |
| no-ngafterviewchecked | ❌ | ✅ | ✅ |
| no-ngondestroy | ❌ | ✅ | ✅ |
| no-input-decorator | ❌ | ✅ | ✅ |
| no-output-decorator | ❌ | ✅ | ✅ |
| no-content-decorator | ❌ | ✅ | ✅ |
| no-view-decorator | ❌ | ✅ | ✅ |
| no-asyncpipe | ❌ | ✅ | ✅ |
| no-reactive-forms | ❌ | ✅ | ✅ |
| no-detectchanges-testing | ❌ | ✅ | ✅ |
| no-changedetectorref | ❌ | ❌ | ✅ |
| no-subscribe-in-component-constructor | ❌ | ❌ | ✅ |
Tip
I also published other lint rules for the Angular injection context.
Why not in Angular ESLint?
I proposed a Pull Request on another topic, but it has been ignored for months, then rejected without a reason. So I decided to publish rules by myself.
Is Angular ESLint required?
No, these rules only depends on TypeScript ESLint.
Is typed linting required?
Typed linting is not required for now, but it could change in the future.
Is adding a plugin making the project heavier?
No, the package has 0 dependency. It just add lint rules using TypeScript ESLint, which is already installed in the project.
MIT