Reference

Reference · Signals

computed()

The computed() function creates a read-only derived signal. It takes a computation function that reads other signals and returns a Signal whose value is lazily recomputed and memoized whenever a source signal changes.

XCODXReference · Updated

Definition

computed() is the Angular function that creates a derived signal — a read-only reactive value defined by other signals. You call it with a computation function that reads one or more signals and returns a value, and you get back a Signal you read by calling it. Its value is always in sync with its sources: when any signal the computation reads changes, the derived value is marked stale and recomputed the next time it is read.

It is the tool for expressing state that depends on other state — a total, a full name, a validity flag — without keeping a second copy in sync by hand. For the concept behind it, see Angular signals — the basics. The writable primitive it derives from is signal().

Syntax

import { computed } from "@angular/core";

const derived = computed(computation);

Parameters

ParameterDescription
computationA zero-argument function that reads one or more signals and returns the derived value. Every signal read inside the computation becomes a dependency, so the derived signal recomputes whenever any of them change. The function should be pure — no side effects.
options (optional)A second argument such as { equal } supplies a custom equality function for the derived value. When a recomputation produces a value considered equal to the previous one, dependents are not notified; the default comparison is Object.is.

The one required argument is the computation function. Keep it pure and cheap to read: it may run whenever a source signal changes and something reads the result, and its only job is to return a value derived from the signals it reads.

Return value

computed() returns a read-only Signal<T> — a getter you call to read the derived value. It has no .set() or .update(), because its value is defined entirely by its computation:

  • Read — call it with no arguments: total() returns the current derived value. Reading inside a template, another computed, or an effect registers a dependency, so that reader re-runs when the derived value changes.
  • Lazy — the computation does not run until something reads the signal. A derived value nobody reads never recomputes, so declaring a computed costs nothing until it is used.
  • Memoized — once computed, the result is cached and returned on subsequent reads without re-running the function, until a source signal actually changes. Read it three times in a row and the computation runs once.
  • Read-only — there is no setter. To change what a computed returns, change one of the signals it reads; the derived value follows automatically.

Because a computed is memoized, it only re-runs when a signal it read has changed and something asks for its value again. This makes deriving state cheap even when the same derived signal is read in many places across a template.

Examples

A derived total

The everyday case: a total derived from a price and a quantity. Change either source signal and the total recomputes on its own — nothing sets it directly, because it is defined by what it reads.

A derived boolean

A computed does not have to be a number. Here a boolean is derived from the length of a name signal, driving a message that flips the instant the input becomes non-empty. The derived flag stays correct with no manual bookkeeping.

// a computed can read several signals and other computeds
const subtotal = computed(() => items().reduce((s, i) => s + i.price, 0));
const tax = computed(() => subtotal() * 0.08);
const grandTotal = computed(() => subtotal() + tax());

Browser & runtime support

computed() is part of the @angular/core package and has been stable since Angular 17, working in every later version including Angular 18. The computation runs in a reactive context, so any signal it reads is tracked automatically; keep it free of side effects, since a computed may run at any time and skips running entirely when nothing reads it. For work that must happen on a change, use an effect instead.

Frequently asked questions

What does computed() return?
It returns a read-only Signal — a getter you call to read the derived value, with no .set() or .update(). Its value is defined by the computation function, so to change it you change one of the signals the computation reads.
Is a computed recalculated on every read?
No. A computed is lazy and memoized: it runs only when something reads it, and it caches the result until a source signal actually changes. Reading it repeatedly without any source change returns the cached value and runs the computation once.
Can a computed depend on another computed?
Yes. A computation can read writable signals and other computed signals freely; each read becomes a dependency. Chaining computeds — subtotal, tax, grand total — is a common and efficient pattern because each layer memoizes.
Why can I not set a computed signal?
A computed is read-only by design because its value is derived entirely from the signals it reads. Giving it a setter would let its value disagree with its sources. To change the result, change a source signal and the computed follows automatically.