
In the world of Angular development, there is a recurring myth: "If it's an Enterprise app, you need a global store." We've all seen it-hundreds of boilerplate files, actions for simple form inputs, and selectors that do nothing more than pluck a single property.
But here is the hard truth: Every line of code you didn't need to write is a debt you don't have to pay.
The Boilerplate Tax
When we jump into NgRx (or similar Redux-pattern libraries) too early, we pay a heavy "boilerplate tax." For a simple feature, you suddenly need:
- An Action to initiate the call.
- An Effect to handle the API.
- Two more Actions for Success/Failure.
- A Reducer to update the state.
- A Selector to read it back.
By the time you've wired this up, you've touched five files just to display a list of users. This fragmentation makes the code harder to follow, harder to refactor, and significantly slower for onboarding new developers.
Signals: The Game Changer
With the arrival of Angular Signals, the argument for global state management has weakened even further. Signals provide a fine-grained reactivity that is:
- Synchronous: No more "race conditions" with async pipes.
- Local by default: State should live where it is used.
- Performant: It triggers change detection only where necessary, helping us hit those 100/100 Lighthouse scores.
When SHOULD you use NgRx?
It's not that NgRx is bad; it's just overused. You truly need it when:
- The same data is consumed and manipulated by multiple, disconnected parts of the app.
- You need complex undo/redo functionality.
- You have high-frequency data streams that require centralized handling.
Conclusion
Stop building "Action-Reducer-Selector" mazes for CRUD operations. Use Signals for local state, Services for shared logic, and save the heavy artillery for the 5% of your app that actually demands it.
Your future self (and your bundle size) will thank you.