DEV Community

Cover image for 🧠 Introducing `reactive-lint`: an Open-Source Angular Linter for Signal-First Architecture
Shrinivass AB
Shrinivass AB

Posted on • Originally published at Medium

🧠 Introducing `reactive-lint`: an Open-Source Angular Linter for Signal-First Architecture

Introducing an open-source Angular linter to enforce signal-first architecture, detect performance issues, and simplify RxJS patterns.

  • Migrating to Angular Signals?
  • Still juggling async pipes and RxJS the old way?
  • Then reactive-lint might just save your future refactors.

As Angular evolves toward Signal-first reactivity, we are writing more reactive code than ever. But with great power (takeUntilDestroyed, toSignal, RxJS) comes… subtle bugs.

So I built a tool for us:

reactive-lint – A Developer-First Linter for Angular Reactivity

🔗 GitHub • 📦 npm


✨ Why I Built It

I love Angular. But I kept seeing the same issues across multiple codebases:

  • async pipe with default change detection
  • subscribe() without cleanup
  • Complex RxJS chains that could be simplified with Signals
  • Observables declared but never used

So I decided to automate the pain away using static analysis, AST parsing, and a bit of Angular love.


💡 What It Does (in Plain English)

reactive-lint is a CLI tool that scans your TypeScript code for anti-patterns in Angular reactivity.

🧩 Rule ✍️ What It Prevents
no-implicit-subscriptions Missing takeUntilDestroyed() in components (leaky subs)
no-async-without-onpush async pipes used without OnPush strategy
prefer-signal RxJS chains that could be Signals
no-unused-observables Observables that aren’t actually used

These are real-world issues Angular devs run into, especially during migration to Signals.


⚡ Try It in 30 Seconds

Install globally or run with npx:

npx reactive-lint "src/**/*.ts"
Enter fullscreen mode Exit fullscreen mode

Angular CLI integration

ng add ng-reactive-lint
Enter fullscreen mode Exit fullscreen mode

Works with standalone components and modules.
No config required for basic usage


📚 Submitted to JOSS

I’ve submitted reactive-lint to the Journal of Open Source Software (JOSS) for peer-reviewed recognition.

This brings transparency and academic validation to the tool and helps it scale beyond one-person dev ops.


🌱 What’s Next?

This is early access, but reactive-lint is already catching bugs in real Angular apps. And it’s picking up steam:

  • 500+ downloads in its first week
  • Rules in place for Signals, RxJS, OnPush, and more
  • Designed to be framework-aware — not just syntax-aware

🙌 Want to Help?

  • Try it in your project and report edge cases
  • ⭐ Star the GitHub repo
  • 💡 Suggest new rules (e.g., lifecycle awareness, zone optimization

🔗Quick Links

npm i reactive-lint
Enter fullscreen mode Exit fullscreen mode

💬 Got Ideas?

Drop your dream lint rule in the comments. Or open an issue. I am iterating based on real usage.
Let’s make Angular reactivity cleaner and faster together!

Top comments (2)

Collapse
 
fyodorio profile image
Fyodor

Why not implement rules (or a plugin) for existing linters instead? A separate dedicated linter is a pita to maintain for consuming projects (not even mentioning a learning curve).

Collapse
 
shrinivassab profile image
Shrinivass AB • Edited

@Fyodor Thanks for your valuable feedback! I appreciate your point about the maintenance and learning curve challenges of a standalone linter. I created ng-reactive-lint to focus specifically on Angular’s reactivity patterns (e.g., Signals, RxJS), which allows for tailored rules like prefer-signal that might not fit neatly into broader linters like ESLint. That said, I agree that an ESLint plugin could make adoption easier for many projects. I’m exploring this as a future feature and would love your input on specific rules or use cases you’d prioritize.