One signal vs. multiple derived signals for complex api responses?

Summary

This incident examines a common architectural dilemma in reactive front‑end systems: should a service expose one large reactive object or many smaller derived signals? The issue surfaced when adding a new form that required raw financial data, forcing a decision between continuing to create more computed slices or consolidating everything into a single source of truth.

Root Cause

The root cause is the accumulation of narrowly scoped computed signals derived from the same API response. Each new UI requirement forces the service to create yet another computed slice, increasing:

  • Repeated iteration over the same data
  • Service bloat as more computed signals accumulate
  • Higher cognitive load for future maintainers
  • Risk of inconsistent transformations across slices

Why This Happens in Real Systems

Real systems drift into this pattern because:

  • Early UI needs are simple, so small computed signals feel clean and modular.
  • Teams optimize for immediate clarity, not long‑term scalability.
  • Signals encourage fine‑grained reactivity, which can accidentally lead to over‑fragmentation.
  • Developers fear exposing raw data, assuming it will cause unnecessary recomputation.

Real-World Impact

This pattern leads to several operational and maintainability issues:

  • Performance overhead from repeatedly mapping the same object into multiple shapes.
  • Service bloat, making the service harder to reason about.
  • Inconsistent data transformations when multiple computed signals evolve independently.
  • Reduced flexibility because every new UI requirement requires a new computed slice.

Example or Code (if necessary and relevant)

// A single computed map that exposes the entire normalized structure
readonly storeSettingsMap = computed(() => {
  const raw = this._rawSettings();
  return raw ?? {};
});

How Senior Engineers Fix It

Senior engineers typically converge on a hybrid model that balances reactivity with maintainability:

  • Expose one normalized source of truth (e.g., storeSettingsMap)
  • Allow components to derive their own computed slices locally
  • Only centralize computed signals when:
    • They are reused across multiple components
    • They are expensive to compute
    • They represent canonical business logic

This approach ensures:

  • Minimal recomputation
  • Maximum flexibility
  • A clean, maintainable service surface area
  • Clear ownership of transformations (UI‑specific vs. domain‑specific)

Why Juniors Miss It

Junior engineers often miss this because:

  • They equate “more signals” with “more reactivity”
  • They try to keep all transformations inside the service, even UI‑specific ones
  • They optimize for local clarity instead of system‑level maintainability
  • They fear exposing raw data, assuming it’s an anti‑pattern

The senior perspective recognizes that a single well‑structured reactive object is often more scalable than many tiny computed slices, especially when UI components can compute their own derived values.

Leave a Comment