Angular v21 Goes Zoneless by Default: What Changes, Why It’s Faster, and How to Upgrade
Table of Contents

If Signals were Angular’s “aha!” moment, Zoneless is the “oh wow—this feels snappy” moment. With Angular v21, new apps use zoneless change detection by default, meaning no more zone.js magic under the hood—just explicit, predictable reactivity powered by Signals.
TL;DR: Bye, Zone.js. Hello smaller bundles, clearer stack traces, and change detection that updates only when you say so—via Signals and events.
Wait… what does “zoneless” actually mean?
Historically, Angular used Zone.js to patch async APIs (timers, events, Promises) and auto-trigger change detection. It was convenient but also eager, sometimes checking way more than necessary. Zoneless removes Zone.js entirely and relies on Signals + template events to know when to update the UI. The result is less work, fewer surprises, and better performance.
What’s new in v21?
Zoneless by default for new projects. v20.2 stabilized the API (provideZonelessChangeDetection()), and PR #63382 makes it the default in ng new. Existing apps can opt in with a one-line provider.
Cleaner builds. No zone.js in your bundle when zoneless—meaning fewer kilobytes and cleaner stack traces.
SSR & error handling ready. Angular added robust error handlers and SSR hooks on the road to zoneless—so the default is production-ready.
Note: v20.2 officially promoted zoneless to stable. v21 is the first major where it’s the default for new apps.
Should you migrate an existing app?
Short answer: Yes, plan it. You’ll likely see fewer unnecessary checks and a smoother mental model—especially if you’re already using Signals.
Typical wins
Predictability: CD runs when inputs/signals/events change, not “whenever anything async happened somewhere.”
Perf: Less over-checking, less patching.
DX: Better stack traces; less “Where did this change detection come from?” moments.
Migration guide
1. Remove Zone.js
Delete zone.js (and zone.js/testing) from angular.json polyfills (build & test). If you have a polyfills.ts, remove import 'zone.js'.
2. Enable zoneless change detection
3. (Recommended) Add browser error listeners
4. Run tests & remove warning
If you see NG0914: using zoneless but still loading Zone.js
“Will my app still update when I click a button?”
Yes. Template events (like (click)
Common patterns that “just work”
Signals drive UI:
HTTP + Signals: Assign the result to a signal (or resource) and bind to it in the template; the UI updates when the signal changes.
markForCheck: Calling markForCheck will basically trigger application rendering, so sometimes, instead of refactoring to signals, a markForCheck will just work too!
Gotchas to check for
Third-party code assuming Zone.js is present. Most major libs are zoneless-ready, but if something patched timers or used Zone APIs directly, you may need an update or a small workaround. (Good news: CDK & Material already have zoneless support.)
Legacy “async triggers UI” assumptions. If you previously depended on a random setTimeout to “poke” CD, switch to signals or dispatch a proper event.
FAQ
Do I have to rewrite everything to Signals?
No. But the more your state is signal-driven, the more you’ll feel the benefits. Components that already use Inputs + events will migrate smoothly.
What about SSR/hydration?
Zoneless has been hardened with SSR error handling and flush timing. If you’re on v20+ SSR, you’re in good shape moving to v21.
Is zoneless actually stable?
Yes—v20.2 promoted it to stable; v21 makes it the default for new apps.
Final take
Zoneless in Angular v21 isn’t just an internal cleanup—it’s a new default that makes Angular feel lighter, sharper, and more intentional. You keep the ergonomics (events, Inputs, Signals) and lose the overhead. If you’ve been on the fence, v21 is your nudge to jump.
Action plan for teams:
Try zoneless on development mode only. Keep it enabled in production.
Verify third-party libs.
Roll out app-wide and enjoy the calm, predictable rendering.
Happy upgrading—and enjoy the silence (of Zone.js). 🥂
Read next

What Is LCP And Why It Matters: Unlock Instant Page Experiences - Part 1
Largest Contentful Paint (LCP) is a Core Web Vital that shapes user perception of speed. This first part explains what LCP is why it matters for SEO and business, and how its phases affect site performance.

What Is LCP And Why It Matters: Unlock Instant Page Experiences - Part 2
Part 2 is a practical walkthrough to diagnose and speed up LCP. Learn to read CrUX trends, profile in Chrome DevTools, preload critical assets, use srcset, defer third-party scripts, and code-split Angular bundles to turn red LCP into green.

Dynamic Angular Config for SSR
Deploy one Angular app for many clients with unique configs—without breaking SSR or DX. Here’s how to unlock dynamic configuration.

Advanced CPU Profiling in Node - Real-Life Examples
Profiling is easiest when it's real. Learn how to capture and make sense of CPU profiles in Node.js across scripts, threads, and processes—then apply it to your own projects.

Advanced CPU Profiling in Node - Profile Data Structure
CPU profiles are more than flame charts—they’re structured JSON files. Learn how nodes, samples, and time deltas form the backbone of DevTools performance data.

Advanced CPU Profiling in Node - Best Practices and Pitfalls
Get deeper insights into your Node.JS performance. Learn how to master advanced CPU profiling with built-in tools, interpret process/thread IDs, and optimize using sampling intervals. Troubleshooting and real examples included.


