I've found a very good senior PHP opportunity! If anyone wants to have some fun, ping me please.

Get in touch
Why Signals Are Angular's Future (And Why You Should Care)
Engineering

Why Signals Are Angular's Future (And Why You Should Care)

Yoana Borissova
9 min read
Angular Signals Reactive Programming State Management Angular 21

Angular Signals arrived with v16, and they’re not just another API addition—they’re a fundamental shift in how Angular handles reactivity. With Angular 21 now zoneless by default, signals have officially become the core of Angular’s reactive model. After spending months integrating them into production systems, I’m convinced they’re the future of Angular development.

What Are Signals, Really?

At their core, Signals are reactive primitives that notify consumers when their values change. Think of them as observables, but simpler and more performant.

import { signal, computed, effect } from '@angular/core';

const count = signal(0);
const doubled = computed(() => count() * 2);

effect(() => {
  console.log(`Count is ${count()}`);
});

The syntax is clean. No subscriptions to manage. No memory leaks to worry about. Just reactive values that “just work.”

The Change Detection Revolution

Here’s where it gets interesting. Traditional Angular uses Zone.js to detect changes across your entire component tree. It’s powerful but expensive.

Signals flip this on its head. With signals, Angular knows exactly what changed and where. No more checking every component when a single value updates.

Angular 21 is zoneless by default. This means signals are no longer a nice-to-have—they’re the primary way Angular tracks changes. Zone.js is officially on its way out, and signals are taking over.

In our trade finance platform at Codexio, switching critical paths to signals reduced change detection cycles by 70%. That’s not a typo.

Real-World Patterns

1. Derived State Without Overhead

readonly user = signal<User | null>(null);
readonly userName = computed(() => this.user()?.name ?? 'Guest');
readonly isAdmin = computed(() => this.user()?.role === 'admin');

These computeds only recalculate when user changes. Zero waste.

2. Effects for Side Effects

effect(() => {
  const currentUser = this.user();
  if (currentUser) {
    this.analytics.track('user_active', currentUser.id);
  }
});

Effects run automatically when dependencies change. No manual subscription wiring.

3. Signal Inputs (Angular 17.1+)

@Component({
  selector: 'app-user-card'
})
export class UserCard {
  user = input.required<User>(); // Signal-based input!
  displayName = computed(() => this.user().displayName);
}

Component inputs as signals. Game changer for OnPush components.

4. HTTP with httpResource (Experimental)

Angular now has experimental httpResource for signal-based HTTP requests:

readonly users = httpResource({
  url: '/api/users',
  loader: () => this.http.get<User[]>('/api/users')
});

// Access in template
<div *ngFor="let user of users.value()">{{ user.name }}</div>

No more manual subscription management. HTTP results as signals.

5. Signal Forms (Experimental)

Signal-based forms are also in development:

readonly form = signalForm({
  email: ['', Validators.required],
  password: ['', Validators.minLength(8)]
});

readonly isValid = computed(() => this.form.valid());
readonly emailValue = computed(() => this.form.controls.email.value());

Forms that play nicely with signals. The future is here.

The Migration Path

Don’t rewrite everything at once. Here’s what actually works:

For Legacy Apps

  1. Use OnPush change detection everywhere - This is non-negotiable. OnPush makes the zoneless transition smooth.
  2. Start writing signals immediately - Don’t wait. New code should use signals.
  3. Don’t fear the hybrid - Running observables and signals side-by-side is perfectly fine. The interop library exists for a reason.
  4. Gradually refactor hot paths - Components that render frequently should move to signals first.

Critical Warning: Kill the Evil Practices

If your codebase has setTimeout() to trigger change detection, fix it NOW.

// EVIL - DO NOT DO THIS
setTimeout(() => {
  this.cdr.detectChanges();
}, 0);

Once everything becomes zoneless, these hacks will break spectacularly. Zone.js was hiding your sins. Signals won’t.

Find them. Kill them. Replace them with proper reactive patterns.

Start With

  1. Hot paths - Components that render frequently
  2. Complex computations - Derived state that’s expensive to calculate
  3. New features - Write everything new with signals

We’ve been running a hybrid approach for months. Some components use observables, some use signals. It’s working fine while we complete the migration.

Signals Are Replacing RxJS (And That’s Good)

Let’s be clear: signals are replacing RxJS in Angular. Not complementing—replacing.

With httpResource handling HTTP requests as signals, signal forms on the horizon, and Angular 21 being zoneless by default, the writing’s on the wall. RxJS served us well, but signals are simpler, more performant, and better suited for Angular’s future.

That said, migration takes time. Angular provides an RxJS interop library to smooth the transition:

// Convert observable to signal
readonly users = toSignal(this.userService.getUsers$(), { 
  initialValue: [] 
});

// Convert signal to observable (when you need it)
readonly users$ = toObservable(this.usersSignal);

Use these bridges while you migrate. Eventually, you won’t need them.

The Gotchas

1. Not a drop-in replacement for everything Don’t convert every BehaviorSubject to a signal. Use the right tool for the job.

2. Learning curve exists Your team needs time to shift mental models. Pair programming helped us a lot.

3. TypeScript inference can be tricky Sometimes you need explicit types:

const users = signal<User[]>([]); // Be explicit

Why This Matters

Angular isn’t just betting on signals—signals are now the foundation. Angular 21 is zoneless by default. Future APIs are signal-first. This isn’t speculation anymore; it’s reality.

More importantly, signals make Angular feel modern again. The developer experience is genuinely delightful. Code is cleaner. Performance is better. Bugs are fewer.

If you’re building Angular apps in 2026 and beyond, signals aren’t optional. They’re the only path forward.

Getting Started

  1. Update to Angular 21 (zoneless by default!)
  2. Enable OnPush change detection on legacy components
  3. Start with a single component - refactor to signals
  4. Hunt down and eliminate setTimeout() change detection hacks
  5. Use computed() for derived state
  6. Add effects where you need side effects
  7. Gradually expand

The best time to start was when signals launched. The second best time is now. The framework is zoneless—your codebase should follow.


Have questions about signals? Hit me up. I’ve probably hit that edge case already.