An Angular-specific linter enforcing optimal reactivity patterns with Signals and RxJS
- 🛠 Architecture Guards
- Enforce
takeUntilDestroyed()
for subscription cleanup - Require
OnPush
withasync
pipes
- Enforce
- ⚡ Performance Optimizations
- Detect unnecessary change detection triggers
- Identify overused RxJS operators
- 🚦 Migration Ready
- Suggest Signal conversions for RxJS chains
- Highlight deprecated reactivity patterns
ng add ng-reactive-lint
npm install -g ng-reactive-lint
Use npx
to run reactive-lint
directly after installing it:
# Lint a specific file
npx reactive-lint src/app/my-component.ts
npx reactive-lint "src/app/**/*.ts"
npx reactive-lint "src/**/*.ts"
Rule ID | Description | Fixable | Angular-Only |
---|---|---|---|
no-implicit-subscriptions | Requires takeUntilDestroyed() |
✅ | Yes |
no-async-without-onpush | Flags missing OnPush |
❌ | Yes |
prefer-signal | Suggests Signal conversions | ✅ | No |
no-unused-observables | Detects unused RxJS streams | ❌ | No |
Metric | Bad Code (Legacy RxJS) | Good Code (Modern Signals) |
---|---|---|
Linting Time (avg) | 1.21 s | 1.86 s |
Memory Usage | 152 MB | 251 MB |
⚠️ Note: The "good" code uses modern Angular patterns (toSignal
,effect
) which involve deeper AST structures and more reactive expressions. This naturally increases parsing time but reflects real-world adoption of Signals. The linter scales robustly with complexity.
npm run build
npm test
npm run lint-example
PRs welcome! See our Contribution Guide.