Zoneless Angular

What It Means & How to Prepare

emoji_objects emoji_objects emoji_objects
Kevin Kreuzer

Kevin Kreuzer

@nivekcode

01.07.2025

7 min read

Zoneless Angular
share

If you’ve spent any time in the Angular ecosystem lately, you’ve likely come across the growing excitement around zoneless change detection. Spoiler: this isn’t just hype — it’s where Angular is headed.

In Angular 20 Zoneless is no longer just experimental, it’s officially in Developer Preview.

But before we dive into the deep end, let’s rewind a bit.

Wait, What’s Zone.js Again?

Zone.js has quietly powered Angular’s change detection for years, working in the background to track asynchronous operations. It’s a third-party library that monkey-patches core browser APIs — like setTimeout, Promise, and addEventListener—so Angular can track when something asynchronous happens and know exactly when to check the DOM for changes. Pretty clever.

But it’s not without its drawbacks — Zone.js can trigger unnecessary change detection cycles which impact performance. The Angular team has long been aware of these limitations, and zoneless mode is their answer to this challenge. By eliminating the reliance on Zone.js, zoneless mode provides a more performant and predictable way to handle change detection in modern Angular applications.

If you’re eager to deepen your understanding of change detection, Zone.js, zoneless approaches, and Angular Signals, be sure to check out our latest book on Angular Signals — it’s packed with insights and practical guidance!

Zoneless Mode: No Zone.js, No Problem

Let’s clear something up: zoneless mode doesn’t change how change detection works — it changes when it gets triggered, and which parts of the application it gets triggered for. This allows Angular to run change detection more selectively and efficiently.

And that’s a big deal. Zoneless mode runs entirely without Zone.js, which means Angular no longer relies on monkey-patched browser APIs to know when to update the UI. Instead, it shifts the responsibility to more explicit triggers — giving you more control and improving performance by avoiding unnecessary change detection cycles and the overhead of a third-party library.

So what actually does trigger change detection in zoneless mode? Here’s the short list:

  • A DOM event is bound in the template (e.g. (click))
  • A Signal is updated
  • The async pipe is used in the template
  • Inputs are changed via ComponentRef.setInput()
  • You manually call ChangeDetectorRef.markForCheck()
  • A component is created or destroyed

To enable Zoneless mode in your app, just call the following method inside the providers in your app.config.ts.

provideExperimentalZonelessChangeDetection();

Once we add the line above we can remove Zone.js completely. Angular will even helpfully yell at you in the console if you forget to remove Zone related things. Thanks, Angular 👏.

When you create a brand-new Angular 20 application using the Angular CLI, you’ll be prompted to choose whether you’d like to enable zoneless change detection from the start which will automatically add the snippet above in your app.config.ts.

Comparing Traditional (Zone.js) and Zoneless Angular

In traditional Angular apps powered by Zone.js, change detection gets triggered by nearly any asynchronous event: a setTimeout, an HTTP request, or even a resolved Promise. It's convenient, but also imprecise — often leading to more change detection cycles than necessary.

Zoneless mode changes the rules. Without Zone.js doing the heavy lifting (and over-triggering), it can be up to you — and Angular’s new reactive tools — to tell the framework when to update the view.

In this section, we’ll look at common patterns, compare how they behave in both modes, and point out where pitfalls can sneak in.

🟢 Scenario 1: Click Handler

A straightforward event handler that updates a property.

{{ count }}
<button (click)="count = count + 1">Update</button>

Zone.js: Count gets correctly updated.
Zoneless: It still works — mainly because we’re assigning a new value inside the click handler. However, a cleaner and more future-proof approach would be to refactor the ****count ****variable into a Signal, giving us better reactivity and alignment with Angular's zoneless best practices.

🔴 Scenario 2: HTTP Request with subscribe

The manual approach to data fetching — ⚠️ Antipattern, should be avoided whenever possible.

{{ data | json }}
this.http.get('/api/posts').subscribe((data) => {
  this.data = data;
});

Zone.js: Triggers change detection
Zoneless: Does not trigger CD. In zoneless mode, Angular no longer automatically knows when to trigger change detection — you’ll need to take control. The recommended approach is to use ****toSignal(), which removes the need for a subscribe call. Next best is the async ****pipe, followed by manual subscriptions combined with signal updates. And lastly — though generally not recommended — you can still call markForCheck() manually if needed.

🟢 Scenario 3: HTTP Request with async Pipe

A common and effective pattern for displaying data in the template that’s fetched as an Observable using HttpClient.

  <pre>{{ posts$ | async | json }}</pre>

Zone.js: Triggers change detection
Zoneless: Works. While the async pipe still works in zoneless mode — and calls markForCheck() internally — it's generally better to convert your observables to signals using toSignal(). This gives you fine-grained reactivity, avoids unnecessary checks, and plays much more nicely with zoneless change detection. The async pipe remains a valid option, but for optimal control and performance, toSignal() is the way to go.

🔴 Scenario 4: Timer-Based Updates

Periodic updates to a property at regular intervals.

  setInterval(() => {
    this.count++;
  }, 1000);

Zone.js: Triggers change detection
Zoneless: It doesn’t work — unless we manually call markForCheck() or update a Signal. Either of those actions would trigger change detection and make the component re-render as expected. The preffered solution is to refactor the count variable into a Signal.

🟢 Scenario 5: Updating a Signal

Welcome to the reactive era.

  count = signal(0);

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

Zone.js: Triggers change detection
Zoneless: Works beautifully. Signals automatically notify the view.

By now, you’ve probably noticed the recurring theme in this post: Signals are the answer. Put simply, use Signals and you’re safe. They offer fine-grained reactivity, integrate seamlessly with zoneless mode, and — perhaps most importantly — are future-proof. In the future Angular might move toward a change detection model where only Signals trigger view updates, therefore making them the most robust choice moving forward.

🟢 Scenario 6: ChangeDetectorRef.markForCheck()

A manual trigger — useful when Angular’s change detection doesn’t automatically pick up changes. Use it to explicitly inform Angular that a check for updates is needed.

  this.data = newValue;
  this.cdRef.markForCheck();

Zone.js: Triggers change detection
Zoneless: Works exactly as intended.

🟢 Scenario 7: Updating Inputs via ComponentRef.setInput()

ComponentRef.setInput() is essentially what happens under the hood when we pass data to a component via its @Input() bindings — it's the low-level mechanism Angular uses to update input properties.

  componentRef.setInput('data', updatedData);
  // or
  <my-component [data]="updatedData"/>

Zone.js: Triggers change detection
Zoneless: Triggers CD by design. Angular listens for input updates even without Zone.js.

How to Get Ready for Zoneless Mode

As Angular moves toward a zoneless future, there are two key strategies to prepare your app. The first — going all-in on OnPush—is often simpler to adopt and doesn't require a full rewrite. The second—using Signals—is more powerful and future-proof but may involve a more substantial refactoring effort.

1. Go All-In On OnPush

If your app already works well with OnPush, you're in great shape — it should work smoothly in zoneless mode too.

2. Use Signals for Everything

Seriously — Signals are like the cheat code for Zoneless Angular. If all your dynamic data is driven by Signals, your app will hum along smoothly even without Zone.js.

And for those inevitable Observable-based APIs? Just convert them:

  const posts = toSignal(this.postService.getPosts());

Boom — reactive, clean, and Zoneless-friendly.

Hybrid Scheduling (> Angular 18+)

Now for the cool part. Since Angular 18, Zoneless and Zone-based worlds collide via hybrid scheduling. Here’s what it fixes:

Previously, if you updated a Signal outside Angular’s zone (like inside setTimeout or runOutsideAngular()), your UI might just… not update. 😬

Now?

   ngZone.runOutsideAngular(() => {
      setInterval(() => signal.set(newValue), 1000);
   });

✅ Works perfectly. Signal updates always schedule change detection, no matter where you are. No more brittle hacks.

(And if hybrid mode causes problems, you can opt out — Angular’s got your back.)

  provideExperimentalZonelessChangeDetection({ ignoreChangesOutsideZone: true })

Zoneless in Angular 20: Developer Preview Time 🎉

Zoneless is no longer just experimental — in Angular 20, it’s officially in Developer Preview.

Over the last six months, Angular’s team made big strides on the Zoneless front, especially around server-side rendering (SSR) and error handling.

Many devs don’t even realize Zone.js is catching errors for them behind the scenes. And during SSR, Zone.js plays a key role in knowing when to flush rendered content to the client. So going Zoneless meant solving those things properly.

In v20:

  • Angular has default handlers for unhandledRejection and uncaughtException in Node.js, keeping your server from crashing during SSR.
  • On the client, you can use provideBrowserGlobalErrorListeners() to catch global errors.

Want to try it? Here’s the setup:

 bootstrapApplication(AppComponent, {
   providers: [
     provideZonelessChangeDetection(),
     provideBrowserGlobalErrorListeners()
   ]
 });

And don’t forget: remove the Zone.js polyfill from angular.json.

If you’re starting a new Angular project from scratch, good news: you can make it Zoneless from the start using the CLI.

Final Thoughts

Zoneless change detection isn’t some optional experiment — it’s the direction Angular is headed. And the sooner you start embracing OnPush, Signals, and smart reactive patterns, the smoother your ride will be.

So whether you’re prepping a legacy app or starting fresh, now’s the time to think beyond the Zone.

And hey, if you’re already building Zoneless apps in the wild, I’d love to hear how it’s going. Ping me anytime. ✌️

Do you enjoy the theme of the code preview? Explore our brand new theme plugin

Skol - the ultimate IDE theme

Skol - the ultimate IDE theme

Northern lights feeling straight to your IDE. A simple but powerful dark theme that looks great and relaxes your eyes.

Show your love for Angular – wear it with pride!

Crafted for Angular Devs. Inspired by Passion.

Crafted for Angular Devs. Inspired by Passion.

From premium T-shirts to dev-friendly accessories, our exclusive collection is made for those who live and breathe Angular.

High-quality, Angular-inspired designs that speak your language. Built by Angular fans – for Angular fans.

Prepare yourself for the future of Angular and become an Angular Signals expert today!

Angular Signals Mastercalss eBook

Angular Signals Mastercalss eBook

Discover why Angular Signals are essential, explore their versatile API, and unlock the secrets of their inner workings.

Elevate your development skills and prepare yourself for the future of Angular. Get ahead today!

Get notified
about new blog posts

Sign up for Angular Experts Content Updates & News and you'll get notified whenever I release a new article about Angular, Ngrx, RxJs or other interesting Frontend topics!

We will never share your email with anyone else and you can unsubscribe at any time!

Emails may include additional promotional content, for more details see our Privacy policy.

Responses & comments

Do not hesitate to ask questions and share your own experience and perspective with the topic

You might also like

Check out following blog posts from Angular Experts to learn even more about related topics like Modern Angular !

Stärken Sie Ihr Team mit unserer umfassenden Erfahrung

Unsere Angular Experten haben viele Jahre damit verbracht, Unternehmen und Startups zu beraten, Workshops und Tutorials zu leiten und umfangreiche Open-Source-Ressourcen zu pflegen. Wir sind sehr stolz auf unsere Erfahrung im Bereich des modernen Frontends und würden uns freuen auch Ihrem Unternehmen zum Aufschwung zu verhelfen.

or