Signals — The New Reactivity

Fine-Grained, Sync, and Glitch-Free

Signals — The New Reactivity

Signals are reactive primitives that replace zone.js change detection for most component state in modern Angular.

4 min read Level 2/5 #angular#signals#reactivity
What you'll learn
  • Create a signal with signal()
  • Read a signal by calling it as a function
  • Update with set and update

Signals are the headline feature of modern Angular. They’re reactive values that templates and other signals automatically subscribe to — no more wondering whether Angular noticed your update.

Creating and Using a Signal

import { Component, signal } from '@angular/core';

@Component({
  selector: 'app-counter',
  standalone: true,
  template: `
    <button (click)="dec()">-</button>
    <span>{{ count() }}</span>
    <button (click)="inc()">+</button>
  `,
})
export class CounterComponent {
  count = signal(0);

  inc() { this.count.update(n => n + 1); }
  dec() { this.count.update(n => n - 1); }
}

Three things to notice:

  • signal(0) creates a writable signal with an initial value.
  • Reading a signal is calling it: count(). The empty parens are required.
  • Writing is .set(value) or .update(fn).

Derived State with computed

import { signal, computed } from '@angular/core';

const price = signal(10);
const quantity = signal(3);
const total = computed(() => price() * quantity());

console.log(total()); // 30
quantity.set(5);
console.log(total()); // 50 — recomputed automatically

computed runs your function on demand and caches the result until one of the signals it reads changes. No subscribe/unsubscribe ceremony.

Why It Matters

Before signals, Angular re-checked the whole component tree any time zone.js detected an async event. Signals tell Angular exactly which parts of which templates depend on which values, so updates touch only the DOM that actually needs to change. Faster, simpler, and easier to reason about.

Interpolation →