A Small Checklist Before Trying Zoneless

Zoneless is not just deleting zone.js. In an existing app, the real work is finding who tells Angular that state changed. Stable since v20.2 and default in new projects from v21; for an existing app, the spike is a different conversation.

Start with a branch, not a promise

Zoneless is the Angular direction for new applications, but an existing app may depend on Zone.js through patterns that were never written down. Treat the first attempt as a compatibility spike.

The first spike is not a migration sprint. It is a way to find the screens where a timer, subscription, overlay, or third-party widget has been leaning on implicit change detection for years.

What to inspect

AreaQuestion
Manual subscriptionsDoes the code update plain fields without a Signal, AsyncPipe, input change, or markForCheck?
TimersDo setTimeout or setInterval callbacks change data that the template reads without notifying Angular?
Stability APIsDoes code wait on NgZone stability events or treat isStable as a runtime gate?
FormsDo reactive forms and validation states update correctly in critical flows?
Third-party UIDo overlays, charts, editors, and maps assume Zone.js?
TestsDoes the test setup still import zone.js/testing?
Find likely zoneless risk pointsbash
rg "NgZone|onStable|onUnstable|onMicrotaskEmpty|isStable|ApplicationRef|setTimeout|setInterval|subscribe\(" src
rg "zone.js|zone.js/testing|provideZoneChangeDetection|provideZonelessChangeDetection" .

A good spike output

A good zoneless spike ends with a short report: flows tested, failures found, dependencies that assume Zone.js, changes required, and a recommendation to adopt, test more, or wait.

A useful report is specific: checkout passed, the chart overlay failed after a timer mutation, the editor package still assumes Zone.js, and the estimated fix is either two components or a dependency upgrade.

If the only output is 'it compiled', the spike did not answer the production question. A production team needs to know what broke, what was untouched, and what would be expensive to fix.

Reusable artifact

Zoneless readiness checklist

  • Create an isolated branch.
  • Remove Zone.js assumptions only inside the spike.
  • Test manual subscriptions, timers, stability APIs, forms, overlays, charts, editors, and maps.
  • Check build and test polyfills.
  • Write a recommendation before planning rollout.

Sources checked

Modern Angular Playbook

This article is one play.

The Modern Angular Playbook collects the diagnostic, the adoption matrix, eleven plays, and the 30-day plan. Free, in English and Portuguese.

You get both PDFs by email, through the Dojo IA list.

Open playbook →

André Ramosavailable for remote roles, UTC−3Get in touch →

Related

Guide · 10 min

The Code That Breaks When Angular Goes Zoneless

A code-heavy review guide for timers, subscriptions, forms, third-party callbacks, and tests before a zoneless Angular spike.

Read article →

Error · 8 min

NG0100 ExpressionChangedAfterItHasBeenCheckedError: Why It Surfaces in Zoneless Angular

Why NG0100 ExpressionChangedAfterItHasBeenCheckedError surfaces after a move to zoneless or Angular 22, what it now means, the test trap with fixture.detectChanges(), and the fixes by where the change came from.

Read article →

Guide · 8 min

OnPush Is the Default in Angular 22: What Breaks and What to Do

Why Angular 22 makes OnPush the default, what actually breaks, the two ways to fix it, and how the migration's Eager additions double as your cleanup backlog.

Read article →