let’s look at the evolution of Angular’s reactive features, focusing on Signals and the new Resource APIs. The aim is to provide a comprehensive understanding of these tools for building faster and cleaner Angular applications.
I. Introduction: A New Dawn for Angular Reactivity
Angular introduces a paradigm shift with explicit reactivity, high performance, and improved developer experience through Angular Signals and associated APIs (computed, linkedSignal, effect, httpResource, resource, rxResource). These features revolutionize state management and data fetching.
II. A Brief History of Reactivity in Angular
- AngularJS: Utilized dirty checking and
$scopevariables, which were simple but led to performance issues at scale.$resourcewas an early data fetching tool.
angular.module('app').factory('User', function($resource) {
return $resource('/api/users/:id', { id: '@id' });
});
- RxJS Era (Angular 2+): Introduced RxJS and Zone.js. Zone.js intercepted asynchronous changes to trigger change detection. RxJS provided powerful Observable streams for asynchronous operations, though mastering it for simple tasks could be complex (RxJS is a Beast so powerfull).
this.http.get('/api/users').pipe(
retry(3),
catchError(err => of([])),
shareReplay(1),
takeUntilDestroy(this.#destroyRef$)
).subscribe(users => {
this.users = users;
});
- The “Why Signals?” Moment: The Angular team wanted to create a smoother, easier to use, and faster way to handle changes in the state, aiming to reduce or eliminate reliance on Zone.js. The Angular team listened to developer feedback, They heard the struggles with Zone.js (bundle size, debugging headaches, performance overhead) and decided it was time for a fresh approach one that would make Angular feel lighter, faster, and more intuitive.
III. The Signal Family: Reactive Superpowers
signal()
- Description: A reactive container that wraps a value and announces changes when updated.
As Alex Rickabaugh said it’s like a box containing two antennas, one transmitter, and one receiver.
- Usage: Declared with
signal(initialValue). - Access/Update: Value is read using
signalName()and updated withsignalName.set(newValue)orsignalName.update(updaterFunction). This makes data flow explicit and observable.
computed()
- Description: A read-only signal whose value is automatically derived from other signals. It functions like a live calculated field.
- Usage:
derivedSignal = computed(() => dependencySignal1() * dependencySignal2()); - Key Features: Recalculates only when its dependencies change, ensuring efficiency. Pure functions are recommended for predictability.
effect()
- Description: A function that executes whenever its signal dependencies are modified. It is used for side effects.
- Use Cases: Logging, synchronizing with
localStorage, interacting with external APIs. - Caution: Should be used Minimally to avoid complexity.
linkedSignal() (Angular 19 MVP)
- Description: A hybrid signal that can derive its value from other signals but remains directly mutable.
- Scenario: You have a
cartItemssignal that automatically calculatestotalPrice, but you also need the ability to manually adjust the total when applying custom discounts or promotional codes that linkedSignal allows you to do seamlessly.
IV. Fetching Data with Finesse: The New Resource Paradigm
Resources simplify asynchronous data management with a Signals first approach, reducing boilerplate for loading states, errors, and re-fetching. (Experimental in Angular 19, evolving in 20/21/…).
resource()
- Description: Designed for any promise based asynchronous operation.
- Use Case: Retrieving data from HTTP or non‑HTTP sources via functions that return Promises.
userPreferences = resource({
params: () => ({ userId: this.currentUserId() }),
loader: async ({ request }) => {
// Custom async operation (not HTTP)
return await localDB.getUserPreferences(request.userId);
}
});
rxResource()
- Description: The Observable-friendly counterpart to
resource(). - Use Case: Integrating RxJS Observables, including existing
HttpClientcalls, with Signals.
livePrice = rxResource({
params: () => ({ symbol: this.stockSymbol() }),
loader: ({ request }) => {
// Returns an Observable (RxJS)
return this.websocketService.watchPrice(request.symbol);
}
});
i remeber also when Alex said regarding rxResource() and Resources look at the return type of these which is ResourceRef which you can extentend and build around it
httpResource() ** The Beast ** (Angular 19.2, evolving in 20/21/…)
- Description: A specialized resource built on
HttpClientthat exposes loading, error, and data as signals. - Features: Built in loading/error states, reactive requests (input signal changes trigger re-fetching), seamless interceptor integration.
- Example: Effortlessly retrieve lists of data with immediate access to
isLoading()anderror()signals. - Recommendation: Best suited for
GETrequests; orPOSTthat is used to get data butPOST/PUT/DELETE/PATCHaka mutation use plainHttpClient.
user = httpResource(() => `/api/users/${this.userId()}`);
V. Angular 21: Polishing the Reactive Gem
Angular 21 deepens the commitment to the Signal-first philosophy with several refinements:
-
Signal Forms: The
[formField]directive replaces[field]for enhanced clarity and power in signal-based forms, including automatic CSS class generation based on form state. -
Router Reactivity: The
Router.isActive()method is replaced by anisActive()function that returns a computed signal of whether the given url is activated in the Router, enabling reactive tracking of active routes. -
Zoneless by Default: New applications now default to zoneless operation, leading to smaller bundles, faster performance, and simplified debugging.
-
Vitest as Default: Vitest is now the standard test runner.
-
AI Tooling: New Angular MCP Server tools introduce AI for smarter workflows and code generation.
VI. Signals vs. RxJS & Community Chatter
Pros of Signals:
- Performance: Fine-grained reactivity minimizes unnecessary re-renders.
- Simpler State Management: More intuitive for local, synchronous component state, reducing boilerplate.
- Zoneless Future: Enables lighter, faster applications without Zone.js.
Cons & Controversies:
- Learning Curve: Developers need to learn both Signals and RxJS.
- Fragmentation: Determining the appropriate use case for each technology is an ongoing discussion.
- Misuse of
effect(): Can lead to unintended loops or performance issues (e.g., writing to another signal in the effect). - Deep Nesting: Excessive signal nesting can complicate debugging.
- Not a Replacement for RxJS: RxJS remains crucial for complex asynchronous streams, event handling they are complementary.
Emerging Best Practices:
- Use
signal()for local state. - Use
computed()for pure derived values. - Use
effect()exclusively for side effects. - Choose
resource/rxResource/httpResourcebased on the asynchronous data source. - If you building Application i guess you will use
httpResource()the most
VII. The Road Ahead: Angular’s Reactive Future
Angular’s future development focuses on:
- Zoneless Adoption: Full adoption of zoneless change detection as the standard.
- Signal Forms Stability: Maturation of experimental Signal Forms into a stable, recommended approach for form management.
- Resource APIs Maturation: Continuous refinement and stabilization of
resource/rxResource/httpResourcefor robust, signal driven data fetching. - Performance Enhancements: Incremental hydration, faster SSR, and further reactivity refinements.
- Developer Experience: Improved tooling, debugging (Signals in DevTools!), and API ergonomics.
- AI Integration: Deeper AI integration for smarter and faster coding.
VIII. Conclusion: Embracing the Reactive Evolution
Angular solidifies Signals and the Resource APIs as core framework components, they provide a powerful, efficient, and easy-to-use way to create modern web applications. Despite a learning curve, the benefits in performance, maintainability, and developer experience are significant, Helping you to create Angular apps that are more responsive and run smoothly.
Source: Original article on HackMD. Local review copy retrieved September 10, 2026.