DEV Community

Cover image for Zoneless Angular Explained — How Change Detection Works Without Zone.js
Mridu Dixit
Mridu Dixit

Posted on

Zoneless Angular Explained — How Change Detection Works Without Zone.js

For years, Angular relied on Zone.js to automatically trigger change detection. It worked—but it also made performance unpredictable and debugging harder.

With modern Angular, especially alongside Signals, Angular can now run without Zone.js.

This article explains:

  • what Zone.js actually did
  • how Angular works without it
  • what triggers change detection now
  • when you should (and shouldn’t) go zoneless

What Zone.js Did in Angular

Zone.js monkey-patches async APIs like:

  • setTimeout
  • Promise
  • fetch
  • DOM events

Whenever anything async happened, Angular would:
👉 re-run change detection for the entire component tree.

Result:

✔ UI always stayed in sync
❌ Too many unnecessary checks
❌ Hard to control performance
❌ “Why did my component re-render?” moments

The Problem with Zone-Based Change Detection

With Zone.js:

  • Any async event can trigger CD
  • Even unrelated components re-check
  • Performance tuning becomes guesswork

This was fine for small apps—but large apps paid the price.

What Is Zoneless Angular?

Zoneless Angular means:

Angular does not automatically run change detection on async events.

Instead, you explicitly tell Angular when state changes.
No magic.
No global re-checks.
Full control.

How Change Detection Works Without Zone.js

🔑 Key Concept

Change detection runs only when Angular knows data has changed.

This happens via:

  • Signals
  • Input changes
  • Explicit triggers

Signals: The Backbone of Zoneless Angular

Example: Signal-based state

count = signal(0);

increment() {
  this.count.update(v => v + 1);
}

Enter fullscreen mode Exit fullscreen mode

Template:

<button (click)="increment()">+</button>
<p>Count: {{ count() }}</p>

Enter fullscreen mode Exit fullscreen mode

What happens?

  • Signal updates
  • Angular knows exactly what changed
  • Only dependent views re-render ✔ No global change detection ✔ No Zone.js involved

Computed Signals (Derived State)

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

Enter fullscreen mode Exit fullscreen mode

Angular tracks dependencies automatically.

Only affected templates update — nothing else.

Effects (Side Effects Without Zone)

effect(() => {
  console.log('Count changed:', this.count());
});

Enter fullscreen mode Exit fullscreen mode

Used for:

  • logging
  • analytics
  • syncing storage
  • triggering API calls

What About Async Operations?

❌ Old Zone-based approach

setTimeout(() => {
  this.value = 10;
}, 1000);

Enter fullscreen mode Exit fullscreen mode

Angular had to guess when to update UI.

✅ Zoneless Approach

value = signal(0);

setTimeout(() => {
  this.value.set(10);
}, 1000);

Enter fullscreen mode Exit fullscreen mode

Signal update → Angular reacts → UI updates.

Running Angular Without Zone.js

Bootstrap example:

bootstrapApplication(AppComponent, {
  providers: [
    provideZoneChangeDetection({
      eventCoalescing: true,
      runCoalescing: true
    })
  ]
});

Enter fullscreen mode Exit fullscreen mode

To fully remove Zone.js:

  • Remove zone.js import
  • Use signals & explicit triggers

What Still Triggers Change Detection?

Even without Zone.js:

  • Signal updates
  • Input bindings
  • Event handlers
  • Manual ChangeDetectorRef calls Angular stays reactive — just not automatic everywhere.

When Zoneless Angular Shines

✅ Large applications
✅ Performance-critical UIs
✅ Apps using Signals heavily
✅ Teams that want predictability

When NOT to Go Zoneless (Yet)

⚠ Legacy apps with heavy RxJS
⚠ Apps relying on implicit async updates
⚠ Teams not ready to refactor state logic

Zoneless is opt-in, not mandatory.

Zoneless + Signals = Predictable Angular

This combo gives Angular:

  • deterministic rendering
  • fewer re-renders
  • easier performance debugging
  • modern reactive mental model

Angular becomes:

“Update only what changed — nothing else.”

Final Thoughts

Zoneless Angular is not about removing features — it’s about removing guesswork.

  • Zone.js = automatic but noisy
  • Zoneless + Signals = explicit and fast

You don’t need to go zoneless everywhere—but understanding it makes you a better Angular developer.

Top comments (0)