Angular signals — read your dependencies first

SkillDev tools

Use whenever writing or editing an Angular `computed()` or `effect()` — including signal-based derivations inside `signalStore` (`withComputed`), component `computed`s, and any `effect`. Applies even for one-line derivations.

Available today. Use it from your connected AI after setup.

Connect ahel once, and every AI you use reads what you have installed.

Then ask your AI: use the Angular signals — read your dependencies first skill

What this skill tells your AI

The instructions your AI receives, as published by fabiangosebrink/dog-rate-app in .claude/skills/angular-signals/SKILL.md and read by ahel’s review.

When you write a computed() or an effect(), read every signal the callback depends on into a const on the first lines of the callback, then work from those locals below. Do not call signal getters inline in the middle of the logic.

// Do this
readonly summary = computed(() => {
  const entries = this.entries();
  const rate = this.rate();

  return entries.reduce((sum, e) => sum + e.amount * rate, 0);
});
// Not this
readonly summary = computed(() =>
  this.entries().reduce((sum, e) => sum + e.amount * this.rate(), 0),
);

The same rule applies to effect():

effect(() => {
  const isOpen = this.isOpen();
  const id = this.itemKey();

  this.sync(id, isOpen);
});

Why this matters

  • Dependencies are visible at a glance. The reader sees exactly what the computed/effect reacts to by reading the top of the block — no scanning the whole body to reconstruct the reactive graph.
  • Tracking is unconditional and predictable. A signal becomes a dependency only if it is read during execution. Reading a signal inside a branch (if, &&, a ternary, an early return) means it is not tracked when that branch is skipped — a classic "why didn't this recompute?" bug. Reading everything up front guarantees a stable dependency set on every run.
  • One consistent value per run. Each signal is read once into a local, so the whole computation sees a single snapshot and you avoid repeated getter calls.

How to apply

  • Put the reads first, one const per signal, before any logic or control flow.
  • Name the local after what it holds (entries, rate, isOpen), not after the signal call.
  • This holds even for trivial one-liners — prefer the explicit block over an inline arrow so the convention is uniform and diffs stay small when logic grows.
  • It applies everywhere signals are consumed reactively: withComputed in a signalStore, component-level computed, and effect.

Consistent with the signal guidance in CLAUDE.md (feed a signal into a store and read it inside a computed) and the state-management skill.

Signals

GitHub stars
99
Forks
11
Last commit
Jul 2026
Advanced
Catalog kind
skill
Gateway key
angular-signals
Source
github.com/fabiangosebrink/dog-rate-app