Back to Blog
January 25, 20265 min read

Angular v21 Signals Deep Dive

This post explains Angular signals in beginner-friendly language, what problem they solve, where they fit compared to RxJS, and why they make component state easier to reason about.

AngularFrontend

Why this topic matters

Frontend state management often feels harder than it should.

You click a button, load data, filter a list, or update a form, and suddenly you are juggling:

  • changing values
  • UI updates
  • subscriptions
  • derived state
  • cleanup logic

Angular signals are important because they make this style of reactivity easier to read and reason about.

If you are new to Angular, the short version is:

  • a signal stores a value
  • Angular tracks where that value is used
  • when the value changes, Angular updates the right places

That is the core idea.


Signals in plain English

A signal is a reactive value.

That means:

  • it holds data
  • Angular knows when that data changes
  • Angular can update the UI or related logic automatically

This is useful because a lot of UI code is really about answering one question:

"When this value changes, what else should update?"

Signals give Angular a simpler way to answer that question.


The main building blocks

signal()

This creates a reactive value.

count = signal(0);

That means count starts at 0, but it is not just a plain number. It is a tracked value.

computed()

This creates a new value based on other signals.

double = computed(() => this.count() * 2);

If count changes, double updates automatically.

This is helpful because you do not need to manually keep both values in sync.

effect()

This runs side-effect logic when signals change.

You might use it for:

  • logging
  • syncing with local storage
  • triggering external behavior

Effects are useful, but they should be used carefully. If everything becomes an effect, your code can become harder to follow.


Why this feels simpler than older patterns

Before signals, Angular developers often relied heavily on:

  • component properties
  • change detection knowledge
  • RxJS streams for many state cases

RxJS is powerful, but for simple component state it can feel heavier than necessary.

Signals improve that experience because:

  • local state becomes easier to read
  • derived values become more direct
  • Angular updates can be more fine-grained
  • there is less boilerplate for straightforward UI state

In other words, signals do not replace thinking. They reduce ceremony around common state patterns.


A practical example

Imagine a page with:

  • a search box
  • a list of products
  • a text label showing how many results match

With signals, you might store:

  • the raw product list
  • the current search term
  • a computed filtered list
  • a computed count

That mental model is clean because each value has a clear role:

  • source state
  • derived state
  • UI output

The component becomes easier to explain to another developer.


Why fine-grained reactivity matters

"Fine-grained reactivity" sounds advanced, but the idea is simple:

when one small value changes, Angular can update only the parts that depend on it

That can help performance because the framework has clearer knowledge of what needs to refresh.

For beginners, the more important benefit is not performance first. It is clarity.

When the dependency relationships are explicit, code tends to be easier to maintain.


Where signals shine most

Signals are especially nice for:

  • local component state
  • derived UI values
  • toggles, counters, filters, and form-adjacent state
  • view models that are easier to express as values than as event streams

They are a great fit when you want the code to read like:

"This value depends on these other values."


When RxJS still makes sense

Signals are not a reason to throw away RxJS.

RxJS is still very useful for:

  • websockets
  • user interaction streams
  • complex async pipelines
  • cancellation flows
  • combining multiple external async sources

A helpful beginner rule is:

  • use signals for local synchronous state and derived UI state
  • use RxJS when you are truly dealing with streams over time

These tools can work together. It is not a competition where one must completely replace the other.


Common beginner mistakes

1. Using effects for everything

If a value can be computed from other values, prefer computed() over effect().

computed() describes state. effect() performs side effects.

Mixing those up makes code harder to understand.

2. Recreating old patterns inside the new API

Signals work best when you embrace their simpler mental model.

If you recreate a lot of manual syncing logic, you lose the benefit.

3. Expecting signals to solve every architecture problem

Signals improve state handling, but they do not replace good component design, clear naming, or healthy boundaries.


A good beginner mental model

You can think about signals with three questions:

  1. What is the source value?
  2. What values can be derived from it?
  3. What side effects should happen when it changes?

That mental split helps keep Angular components calm and readable.


Final thoughts

Signals matter because they make Angular state feel more direct.

For many developers, the biggest win is not just performance. It is that the code reads more like the UI behavior you are trying to express.

If a feature is mostly about values changing and the interface reacting to those changes, signals are often a very natural fit.