For years, Angular developers lived in a world powered by RxJS.
Streams, subscriptions, operators, Subjects — if you wanted reactive behavior in Angular, RxJS was the way.
Then Angular introduced Signals, a new reactivity model that promised something developers had been craving:
Simpler state management with less boilerplate.
Suddenly, many Angular developers began asking:
- Do we still need RxJS Subjects?
- Are Signals replacing RxJS?
- Should we rewrite everything?
Before we panic-delete our Subject imports, let's understand what actually changed.
A Quick Mental Model
Think of it like this:
Signals are like a spreadsheet cell.
When a value changes, everything depending on it updates automatically.
RxJS is like a pipeline of events.
Data flows through operators, transformations, and async processes.
Both are reactive — but they solve different problems.
The Old Angular Pattern: RxJS Everywhere
Before Signals, developers often used BehaviorSubject even for simple component state.
Example:
private countSubject = new BehaviorSubject<number>(0);
count$ = this.countSubject.asObservable();
increment() {
this.countSubject.next(this.countSubject.value + 1);
}
Template:
{{ count$ | async }}
For beginners, this raised questions like:
- Why do I need
BehaviorSubject? - Why
asObservable()? - Why the async pipe?
A lot of code… for something as simple as a counter.
The Signals Way
Now the same example becomes:
count = signal(0);
increment() {
this.count.update(v => v + 1);
}
Template:
{{ count() }}
That's it.
- No subscriptions.
- No async pipe.
- No Subject.
This is where Signals shine.
Where Signals Truly Replace RxJS Subjects
Signals are fantastic for application state.
1. Component State
Instead of:
loading$ = new BehaviorSubject(false);
You can simply write:
loading = signal(false);
2. Derived State
Previously:
total$ = combineLatest([price$, quantity$]).pipe(
map(([p, q]) => p * q)
);
With Signals:
total = computed(() => price() * quantity());
This reads almost like plain English.
3. UI Reactivity
Signals integrate directly with Angular change detection.
Update the signal → UI updates automatically.
No subscriptions needed.
But Signals Don't Replace Everything
Here's where beginners often misunderstand.
Signals manage state.
RxJS manages streams.
Those are different things.
Where RxJS Subjects Are Still the Better Choice
1. Event Streams
Imagine a chat application receiving messages.
messages$ = new Subject<Message>();
socket.onmessage = msg => {
this.messages$.next(msg);
};
This is a stream of events, not a single state value.
Signals are not designed for this pattern.
2. Complex Async Workflows
Consider a search box.
You want to:
- debounce typing
- cancel previous requests
- fetch new results
RxJS handles this beautifully:
search$
.pipe(
debounceTime(300),
switchMap(query => this.http.get(`/api?q=${query}`))
)
.subscribe();
Signals do not provide operators like:
- debounce
- switchMap
- retry
- merge streams
That is RxJS territory.
3. WebSockets & Real-Time Data
Live data streams fit RxJS naturally.
Examples include:
- stock price feeds
- live chat
- multiplayer game updates
Signals are state holders, not event streams.
The Best Approach: Use Both
The Angular team never intended Signals to replace RxJS.
Instead, they built tools to connect them together.
Observable → Signal
users = toSignal(this.http.get<User[]>('/api/users'));
Now your template can simply use:
{{ users()?.length }}
Signal → Observable
user$ = toObservable(userSignal);
Useful when integrating with RxJS pipelines.
A Practical Architecture
Modern Angular apps often follow this pattern:
RxJS handles data flow.
Signals handle UI state.
When to Use Signals
Use Signals when dealing with:
- component state
- UI state
- derived values
- reactive templates
- replacing
BehaviorSubjectin components
When to Use RxJS Subjects
Use Subjects when dealing with:
- event streams
- async workflows
- WebSockets
- complex operator chains
- cancellation logic
My Take
Angular development is evolving toward something simpler:
- Less boilerplate
- Clearer reactivity
- Better separation between state and streams
In many cases, Signals can replace BehaviorSubject when managing simple component or service state.
However, RxJS remains incredibly powerful for:
- asynchronous streams
- event pipelines
- complex reactive workflows
Signals didn't replace RxJS.
They just gave Angular developers the right tool for the right job.

Top comments (0)