Angular Signals vs RxJS: Which Should You Use in 2025?

🔍 Introduction
Angular's new reactive system, Signals, introduced in Angular 16 and stabilized in Angular 17, has shaken up how we think about state management and reactivity in Angular apps.
As someone who’s worked with RxJS-heavy enterprise Angular apps and recently adopted Signals in a new project, I’ve had the chance to compare both in real-world scenarios.
In this post, we’ll explore:
What Signals and RxJS are
Key differences in reactivity
Use cases for each
When to use Signals, RxJS, or both
Real-world examples
🧠 What Are Angular Signals?
Signals are a new reactivity primitive built into Angular. They allow you to declare reactive values in a synchronous, fine-grained way — similar to how frameworks like SolidJS and Vue handle reactivity.
import { signal, computed } from '@angular/core';
const count = signal(0);
const double = computed(() => count() * 2);
count.set(5); // double() now returns 10
✅ Pros:
Synchronous and predictable
No subscriptions or teardown needed
Great for component-local state
Tight integration with the Angular template system
🔄 What About RxJS?
RxJS (Reactive Extensions for JavaScript) is a powerful event-stream library used extensively in Angular for:
Form and user input streams
HTTP requests
Complex data streams
Shared state across services
import { BehaviorSubject } from 'rxjs';
const count$ = new BehaviorSubject(0);
const double$ = count$.pipe(map(val => val * 2));
✅ Pros:
Powerful for async/event-driven scenarios
Operators like
debounceTime
,switchMap
,mergeMap
Battle-tested in large Angular apps
⚔️ Signals vs RxJS – Key Differences
Feature | Angular Signals | RxJS |
Type | Synchronous | Asynchronous / Event-driven |
Learning Curve | Low (for Signals) | Medium to high |
Subscriptions | ❌ No | ✅ Required (unsubscribe) |
Integration with Angular | ✅ Deeply integrated | ✅ Supported via async pipe |
Ideal For | Local state, computations | Streams, HTTP, global state |
Lazy Evaluation | ✅ Yes | ❌ Not by default |
🎯 When to Use Angular Signals
Use Signals when:
You manage local UI state (e.g., tabs, toggles, component flags)
You need computed values with dependencies
You want minimal boilerplate (no Subject/Subscription)
You’re building standalone components
export class CounterComponent {
count = signal(0);
double = computed(() => this.count() * 2);
increment() {
this.count.set(this.count() + 1);
}
}
✅ Signals shine in pure, isolated, component-local logic.
🌐 When to Use RxJS
Use RxJS when:
You’re dealing with asynchronous data (e.g., HTTP, WebSocket)
You need to combine multiple streams (mergeMap, switchMap)
You’re working in shared services, app-wide state
You need operators like
debounceTime
,retry
,takeUntil
this.user$ = this.userService.getUser().pipe(
retry(3),
catchError(() => of(null))
);
✅ RxJS is still the go-to for advanced stream orchestration.
💡 Can You Use Both? (Yes!)
Absolutely. In fact, this will be the default hybrid strategy in modern Angular apps.
💡 Use Signals for local state and RxJS for async data streams or services.
Angular now supports bridging the two:
import { toSignal } from '@angular/core/rxjs-interop';
this.userSignal = toSignal(this.userService.getUser$());
This makes them interoperable, so you can gradually migrate or mix based on need.
⚠️ Signals Are Not a Drop-in Replacement
👉 Don’t try to replace all RxJS code with Signals.
Signals are not meant for asynchronous flows, debounced form inputs, or complex operators.
Instead, think of Signals as a complement to RxJS — for simpler, cleaner local state.
🧪 Real-World Example (RxJS + Signals Hybrid)
@Component({...})
export class ProfileComponent {
private userId$ = this.route.paramMap.pipe(
map(params => params.get('id')),
filter(Boolean)
);
userSignal = toSignal(
this.userId$.pipe(
switchMap(id => this.userService.getUserById(id))
),
{ initialValue: null }
);
}
🚀 Elegant, readable, and reactive — best of both worlds.
✅ Conclusion: What Should You Use?
Scenario | Recommendation |
Local component state | Signals |
Async HTTP/API calls | RxJS |
Event-driven workflows | RxJS |
Computed values & dependencies | Signals |
Shared service state | RxJS (maybe Signals later) |
Performance-optimized UIs | Signals |
Angular in 2025 = Signals + RxJS, not one or the other.
📌 Final Thoughts
As the Angular ecosystem evolves, Signals will likely become the standard for most UI-level logic. But RxJS isn't going anywhere — and the ability to use both gives us more flexibility and control than ever.
💬 What’s your take? Have you started using Signals in your Angular projects? Let me know in the comments or on LinkedIn!
🔗 Want More?
Signals in Angular Docs
toSignal Interop Utilities
Stay tuned for my next post: "Building a Full Feature with Signals + RxJS in Angular 17"
Subscribe to my newsletter
Read articles from Prashant Kumar directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
