💡 TL;DR: Angular 18 signals make state management reactive, simple, and performant — all without RxJS ceremony. Perfect for managing local UI state in a predictable, clean way.
What is Angular 18?
Angular 18 continues the framework’s evolution towards greater performance and developer experience. One of its most exciting features is Signals — a reactive primitive introduced to enable fine-grained reactivity with better performance and predictability than the existing RxJS-driven model.
What Are Signals?
Signals are a new reactive state management mechanism in Angular. They are mutable, trackable, and automatically trigger updates when their value changes — making them a natural fit for UI binding and reactive logic.
Unlike BehaviorSubject or Observable, signals are synchronous, pull-based, and work without the need for subscriptions or async pipes.
Why Do We Need Signals?
In traditional Angular, reactive state handling often involved RxJS. While powerful, it required a lot of boilerplate and could lead to unreadable and complex code for smaller applications.
With signals, Angular developers get:
- Better performance (fewer change detection cycles)
- Simpler mental model
- Cleaner templates and components
- No need to unsubscribe
A Quick Example of Signals
Here’s how you define and use signals in Angular 18:
🔹 Define a signal
import { signal } from "@angular/core"; export class CounterComponent { count = signal(0); increment() { this.count.update((c) => c + 1); } }
🔹 Use it in your template
<button (click)="increment()">Increment</button> <p>Count: {{ count() }}</p>
Notice how count() is used as a function, not a variable. That's because it's a getter function behind the scenes.
Computed Signals
You can derive values from other signals using computed:
import { computed, signal } from "@angular/core"; export class PriceComponent { quantity = signal(2); pricePerUnit = signal(10); totalPrice = computed(() => this.quantity() * this.pricePerUnit()); }
Now totalPrice() will automatically update if either quantity or pricePerUnit changes.
Effects
Want to react to changes? Use effect:
import { effect } from "@angular/core"; effect(() => { console.log("Total price changed:", this.totalPrice()); });
This is Angular’s version of watchEffect from Vue or MobX reactions — a way to respond to state changes.
What’s in it for you?
If you’ve struggled with boilerplate-heavy state handling or unnecessary change detection, signals offer a cleaner, leaner alternative. They bring Angular closer to the reactive programming comfort that developers experience in frameworks like Solid.js or Vue 3 — without giving up Angular’s structure.
Angular 18's signal API is the beginning of a broader reactivity overhaul that will eventually power more optimized rendering and a zone-less Angular future. 🚀