Zoneless Angular
What It Means & How to Prepare

Kevin Kreuzer
@nivekcode
01.07.2025
7 min read

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
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.

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

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!
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 !

Will Signals replace RxJs?
A Practical Guide to Understanding the Differences and Choosing the Right Tool for the Job

Kevin Kreuzer
@nivekcode
13.03.2025
4 min read

Stop Misusing Effects! Linked Signals Are the Better Alternative!
State synchronization with Angulars brand new linked Singlas API for a cleaner and more maintainable approach.

Kevin Kreuzer
@nivekcode
10.02.2025
4 min read

Hawkeye, the Ultimate esbuild Analyzer
Effortlessly analyze your JS bundles and uncover actionable insights to boost performance and enhance user experience.

Kevin Kreuzer
@nivekcode
28.12.2024
10 min read
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.