Introduction
Angular has always been one of the strongest frameworks for building enterprise-grade web applications.
But until now, its reactivity model (based on change detection with Zone.js) had certain limitations — especially in large-scale or performance-heavy applications.
That’s where Angular Signals come in.
Introduced in Angular v16, Signals provide a modern, predictable, and efficient way to handle reactive state management — without needing external libraries like RxJS for everything.
In this article, we’ll break down what Signals are, how they work, and how you can use them to make your Angular apps faster, cleaner, and more maintainable.
What Are Signals in Angular?
A Signal is a special kind of variable that reacts automatically when its value changes.
It holds a value, and whenever that value updates, Angular automatically updates the parts of the UI that depend on it.
Think of Signals as state containers that are:
🧠 Simple Example
import { Component, signal } from '@angular/core';
@Component({
selector: 'app-counter',
template: `
<h2>{{ count() }}</h2>
<button (click)="increase()">Increase</button>
`
})
export class CounterComponent {
count = signal(0);
increase() {
this.count.update(v => v + 1);
}
}
✅ Here’s what happens:
signal(0) creates a reactive state variable named count.
count() reads its value.
When increase() updates it, Angular automatically re-renders only that part of the UI.
No need for ChangeDetectorRef, no need for Zone.js — Angular does it smartly.
Why Use Signals?
Traditional Angular apps use Zone.js and RxJS for state updates. While RxJS is powerful, it can feel complex for simple reactivity needs.
Signals simplify this by giving you:
Different Ways to Use Signals
1. Read and Write
const name = signal('Rajesh');
console.log(name()); // 'Rajesh'
name.set('Gamee Rajeshbhai');
console.log(name()); // 'Gamee Rajeshbhai'
2. Update
const counter = signal(1);
counter.update(value => value + 1);
This is a common pattern in counters, pagination, or quantity updates.
3. Computed Signals
You can create computed signals that depend on other signals.
const firstName = signal('Rajesh');
const lastName = signal('Gami');
const fullName = computed(() => `${firstName()} ${lastName()}`);
console.log(fullName()); // Rajesh Gami
When either firstName or lastName changes,
fullName automatically recalculates — no manual code required!
4. Effects
Effects are side operations that run whenever a signal changes — like calling an API or logging data.
effect(() => {
console.log('Counter changed:', counter());
});
If counter updates anywhere in the app, this effect will run automatically.
Signals vs Observables
| Feature | Signals | Observables |
|---|
| Type | Stateful variable | Stream of events |
| Simplicity | Very simple | More advanced |
| Subscription | Not needed | Required |
| Async | No | Yes |
| Best For | UI state management | Event/data streams (HTTP, sockets) |
👉 Use Signals for local, UI-level state.
👉 Use Observables for async data streams (like API calls or sockets).
Flowchart – How Signals Work in Angular
[Signal Created] → [Value Changes] → [Dependent Computed/Effect Runs] → [Angular Updates UI Automatically]
Unlike traditional change detection, Angular knows exactly what changed — so only that component or template fragment is updated.
This results in faster, more predictable, and scalable UIs.
Example – Using Signals in a Real Component
Let’s build a small cart system with Signals:
import { Component, signal, computed } from '@angular/core';
@Component({
selector: 'app-cart',
template: `
<h3>Total Items: {{ totalItems() }}</h3>
<h3>Total Price: ₹{{ totalPrice() }}</h3>
<button (click)="addItem(100)">Add ₹100 Item</button>
`
})
export class CartComponent {
items = signal<number[]>([]);
totalItems = computed(() => this.items().length);
totalPrice = computed(() => this.items().reduce((a, b) => a + b, 0));
addItem(price: number) {
this.items.update(list => [...list, price]);
}
}
✅ Output
No manual subscriptions.
No explicit detectChanges().
Just pure reactive simplicity.
Signals and Zoneless Angular
In Zoneless Angular, change detection isn’t triggered automatically by async tasks.
Signals fix this problem beautifully — they tell Angular exactly when and what to re-render.
So if you combine:
…you get the fastest and cleanest Angular app ever built.
When to Use Signals
| Use Case | Recommended |
|---|
| Component-level state | ✅ Yes |
| Global state (with small data) | ✅ Yes |
| Async API calls | ⚠️ Combine with RxJS |
| Complex global state | ❌ Use NgRx or a mix of both |
Advantages of Using Signals
Performance Boost: Only affected components update.
Simpler State Management: No need for boilerplate.
Predictable Behavior: No random UI refreshes.
Seamless Debugging: You can track signal changes easily.
Future-Proof: Angular team is evolving Signals as the core reactive system.
Future of Angular with Signals
Angular team is working to make Signals the heart of the framework — even replacing parts of the current change detection model.
In future versions (Angular 18+), Signals will:
So learning Signals today means you’re ready for the future Angular architecture.
Conclusion
Signals bring a fresh, modern, and high-performance reactivity model to Angular.
They remove the need for complex RxJS logic for local states and make UI updates smooth and predictable.
If you’re an Angular developer aiming to write cleaner, faster, and more reactive apps,
it’s time to embrace Signals — and leave manual subscriptions behind.
✅ In short
Signals make Angular reactive, clean, and powerful — the way modern web apps should be.