Halodoc migrated their production Angular SSR application from Zone.js-driven change detection to zoneless mode using provideZonelessChangeDetection(), which became stable in Angular 20. The migration eliminated an entire class of SSR errors (Zone is not defined, ZoneAwarePromise is not a constructor) caused by zone.js/node patching Node.js built-ins. Key steps included updating app.config.ts, adding ChangeDetectionStrategy.OnPush to all components, converting fakeAsync/tick tests to async/await, and removing zone.js from polyfills. Challenges included migrating a shared component library, wrapping legacy third-party libs like SlickCarousel that assumed Zone-patched APIs, and fixing SSR cold-start race conditions now exposed without Zone's task-queue tracking. Bundle savings were 12–29 KB gzipped. The team packaged the process as a Claude Code skill for reuse. The full migration was completed in two days with AI assistance handling mechanical refactoring.
Table of contents
The Trigger — Why Now?Why We MigratedProject ScopeThe MigrationRollback PlanThe Results: Bundles, SSR & LighthouseChallengesConclusionReferencesJoin usAbout HalodocSort: