Signals: Modern Reactivity in Angular
13 min read
What Are Signals?
Signals are Angular's built-in reactivity primitive, introduced in Angular 16 and stabilized in v17/v18. A signal is a wrapper around a value that notifies interested consumers when the value changes. They provide fine-grained reactivity without the complexity of RxJS for simple state.
ts
import { Component, signal, computed, effect } from '@angular/core';
@Component({
selector: 'app-signals-demo',
standalone: true,
template: `
<p>Count: {{ count() }}</p>
<p>Double: {{ double() }}</p>
<p>Status: {{ status() }}</p>
<button (click)="increment()">+</button>
<button (click)="decrement()">-</button>
<button (click)="reset()">Reset</button>
`
})
export class SignalsDemoComponent {
// Writable signal
count = signal(0);
// Computed signal — recalculates when count changes
double = computed(() => this.count() * 2);
status = computed(() => {
const c = this.count();
if (c > 10) return 'High';
if (c > 0) return 'Normal';
return 'Zero or below';
});
constructor() {
// Effect runs whenever its dependencies change
effect(() => {
console.log('Count changed:', this.count());
});
}
increment() { this.count.update(c => c + 1); }
decrement() { this.count.update(c => c - 1); }
reset() { this.count.set(0); }
}Signal API at a Glance
signal(initialValue)— create a writable signalsignal.set(value)— replace the signal valuesignal.update(fn)— update based on current valuesignal.mutate(fn)— mutate in place (arrays/objects)computed(() => ...)— derive a read-only signal from otherseffect(() => ...)— run side effects when dependencies changetoObservable(signal)— bridge a signal to an RxJS ObservabletoSignal(observable$)— bridge an Observable to a signal
Signals enable zoneless change detection in future Angular versions. For new projects, prefer signals for local component state. Use RxJS when dealing with asynchronous streams, HTTP, or complex event processing.
Ready to test yourself?
Practice Angular— quiz & coding exercises