Angular Upgrade Planner
Pick a source and target Angular version (8–22) for an ordered, checkable upgrade plan — ng update commands, breaking changes, deprecations, and migrations.
Choose your upgrade path
Angular 8 → Angular 9
(5 steps)Commit or stash all work, then make sure you are on the latest minor/patch of your current major before running ng update. Upgrade exactly one major at a time and run the app/tests after each hop.
Angular 9 needs Node.js 10.13 or newer and TypeScript 3.6 to 3.8. Update tslib to 1.10.
Check your Node.js & TypeScript versions for Angular 9 →Update the core framework and CLI together. This applies the official automatic migration schematics for this version.
ng update @angular/core@9 @angular/cli@9
Angular 9 switches to the Ivy rendering engine by default and runs ngcc to compile your dependencies. Expect stricter template type-checking and some changed runtime behavior; you can temporarily opt out with enableIvy: false.
ng update applies the v9 schematics: Renderer → Renderer2, adding @Injectable/@Directive to undecorated classes, the ModuleWithProviders generic, and removing the now-optional { static: false } from @ViewChild/@ContentChild queries.
Sources: Angular Update Guide: v8 → v9 · Angular 9.0.0 release notes
Angular 9 → Angular 10
(5 steps)Commit or stash all work, then make sure you are on the latest minor/patch of your current major before running ng update. Upgrade exactly one major at a time and run the app/tests after each hop.
Angular 10 requires TypeScript 3.9 and bumps several dependencies. tslib moves to a peer dependency.
Check your Node.js & TypeScript versions for Angular 10 →Update the core framework and CLI together. This applies the official automatic migration schematics for this version.
ng update @angular/core@10 @angular/cli@10
A new default browserslist drops some older browsers, and projects get stricter settings. Angular Material adds a new date range picker. Review tsconfig and any removed browser support.
ViewEncapsulation.Native, WrappedValue, and some ESM5/FESM5 outputs are deprecated. Consider ng new --strict for new projects.
Sources: Angular Update Guide: v9 → v10 · Angular 10.0.0 release notes
Angular 10 → Angular 11
(5 steps)Commit or stash all work, then make sure you are on the latest minor/patch of your current major before running ng update. Upgrade exactly one major at a time and run the app/tests after each hop.
Angular 11 requires TypeScript 4.0 and drops support for IE9, IE10, and IE mobile.
Check your Node.js & TypeScript versions for Angular 11 →Update the core framework and CLI together. This applies the official automatic migration schematics for this version.
ng update @angular/core@11 @angular/cli@11
Some async test helpers and CollectionChangeRecord are deprecated. Update to the recommended TestBed patterns.
webpack 5 support is available (experimental) via a package.json resolutions entry. Hot Module Replacement can be enabled with ng serve --hmr. Automatic inline fonts and faster builds are included.
Sources: Angular Update Guide: v10 → v11 · Angular 11.0.0 release notes
Angular 11 → Angular 12
(5 steps)Commit or stash all work, then make sure you are on the latest minor/patch of your current major before running ng update. Upgrade exactly one major at a time and run the app/tests after each hop.
Angular 12 requires Node.js 12.14 or newer and TypeScript 4.2+.
Check your Node.js & TypeScript versions for Angular 12 →Update the core framework and CLI together. This applies the official automatic migration schematics for this version.
ng update @angular/core@12 @angular/cli@12
Angular 12 deprecates View Engine; the framework is effectively Ivy-only going forward. Production build becomes the default for ng build, and IE11 support is deprecated.
node-sass is no longer supported. Run the Sass migration and switch your styles to dart-sass. Nullish coalescing (??) is now supported in templates.
Sources: Angular Update Guide: v11 → v12 · Angular 12.0.0 release notes
Angular 12 → Angular 13
(5 steps)Commit or stash all work, then make sure you are on the latest minor/patch of your current major before running ng update. Upgrade exactly one major at a time and run the app/tests after each hop.
Angular 13 requires a current Node.js (12.20+, 14.15+, or 16.10+) and TypeScript 4.4. New apps get RxJS 7.4; existing apps can stay on RxJS 6.5+.
Check your Node.js & TypeScript versions for Angular 13 →Update the core framework and CLI together. This applies the official automatic migration schematics for this version.
ng update @angular/core@13 @angular/cli@13
View Engine is removed from the framework and libraries are now published in Ivy partial-compilation format. Older View Engine libraries still work through ngcc until v16. Internet Explorer 11 support is removed, and string-based loadChildren must use dynamic import().
ModuleWithProviders now requires a generic type, entryComponents is no longer needed/used, and renderModuleFactory is removed. The migration fixes most of these automatically.
Sources: Angular Update Guide: v12 → v13 · Angular 13.0.0 release notes
Angular 13 → Angular 14
(5 steps)Commit or stash all work, then make sure you are on the latest minor/patch of your current major before running ng update. Upgrade exactly one major at a time and run the app/tests after each hop.
Angular 14 requires Node.js 14.15+ or 16.10+ and TypeScript 4.6 to 4.8.
Check your Node.js & TypeScript versions for Angular 14 →Update the core framework and CLI together. This applies the official automatic migration schematics for this version.
ng update @angular/core@14 @angular/cli@14
FormControl, FormGroup, and FormArray are now strictly typed. Existing forms code may stop compiling; the migration swaps to Untyped* variants so you can adopt typing gradually.
Standalone components/directives/pipes arrive in developer preview, along with the inject() function, NgOptimizedImage (preview), functional Router guards (CanMatch), and the page Title strategy.
Convert constructor injection to inject() online →Sources: Angular Update Guide: v13 → v14 · Angular 14.0.0 release notes
Angular 14 → Angular 15
(5 steps)Commit or stash all work, then make sure you are on the latest minor/patch of your current major before running ng update. Upgrade exactly one major at a time and run the app/tests after each hop.
Angular 15 requires a current Node.js (14.20+, 16.13+, or 18.10+) and TypeScript 4.8 or 4.9.
Check your Node.js & TypeScript versions for Angular 15 →Update the core framework and CLI together. This applies the official automatic migration schematics for this version.
ng update @angular/core@15 @angular/cli@15
Angular Material components are rebuilt on Material Design Components (MDC). DOM structure and CSS change — audit custom Material styles and run the Material migration. Legacy components are available under @angular/material/legacy-* temporarily.
bootstrapApplication, provideRouter, provideHttpClient, functional Router guards, the directive composition API, and NgOptimizedImage are all stable. Consider adopting standalone bootstrap.
Sources: Angular Update Guide: v14 → v15 · Angular 15.0.0 release notes
Angular 15 → Angular 16
(6 steps)Commit or stash all work, then make sure you are on the latest minor/patch of your current major before running ng update. Upgrade exactly one major at a time and run the app/tests after each hop.
Angular 16 requires Node.js 16.14+ or 18.10+ and TypeScript 4.9.3 up to 5.1.
Check your Node.js & TypeScript versions for Angular 16 →Update the core framework and CLI together. This applies the official automatic migration schematics for this version.
ng update @angular/core@16 @angular/cli@16
Non-destructive hydration is available in developer preview with provideClientHydration (SSR still uses @nguniversal in v16). An esbuild-based build and dev server is also in developer preview.
The Angular Compatibility Compiler (ngcc) is removed, so any dependency still shipped in View Engine format fails to build. Update or replace those libraries before this hop.
Angular Signals arrive in developer preview, along with takeUntilDestroyed/DestroyRef, required inputs, and binding Router data/params/title to component inputs via withComponentInputBinding. Self-closing tags are supported.
Sources: Angular Update Guide: v15 → v16 · Angular 16.0.0 release notes
Angular 16 → Angular 17
(6 steps)Commit or stash all work, then make sure you are on the latest minor/patch of your current major before running ng update. Upgrade exactly one major at a time and run the app/tests after each hop.
Angular 17 requires Node.js 18.13+ or 20.9+ and TypeScript 5.2 up to 5.4.
Check your Node.js & TypeScript versions for Angular 17 →Update the core framework and CLI together. This applies the official automatic migration schematics for this version.
ng update @angular/core@17 @angular/cli@17
New applications use the esbuild + Vite application builder (@angular-devkit/build-angular:application) with faster builds and a Vite dev server. Existing apps keep the webpack builder until migrated. SSR moves to the new @angular/ssr package and is offered during ng new.
New built-in control flow replaces *ngIf/*ngFor/*ngSwitch — run ng generate @angular/core:control-flow to migrate templates. Deferrable views (@defer) enable lazy loading of template blocks.
Convert a template to @if/@for online →ng generate @angular/core:control-flow
signal() and computed() are stable (effect() stays in developer preview until v20), afterRender/afterNextRender hooks are added in developer preview, and the View Transitions API is supported via withViewTransitions.
Sources: Angular Update Guide: v16 → v17 · Angular 17.0.0 release notes
Angular 17 → Angular 18
(5 steps)Commit or stash all work, then make sure you are on the latest minor/patch of your current major before running ng update. Upgrade exactly one major at a time and run the app/tests after each hop.
Angular 18 requires Node.js 18.19.1+, 20.11.1+, or 22, and TypeScript 5.4 or 5.5.
Check your Node.js & TypeScript versions for Angular 18 →Update the core framework and CLI together. This applies the official automatic migration schematics for this version.
ng update @angular/core@18 @angular/cli@18
provideExperimentalZonelessChangeDetection lets you trial zoneless apps, and event replay for SSR is available in preview. Review zone-dependent code before trying zoneless.
Angular Material 3 is stable, the build tooling is published as @angular/build, deferrable views and built-in control flow are stable, ng-content supports default/fallback content, and route redirects can be functions.
Sources: Angular Update Guide: v17 → v18 · Angular 18.0.0 release notes
Angular 18 → Angular 19
(5 steps)Commit or stash all work, then make sure you are on the latest minor/patch of your current major before running ng update. Upgrade exactly one major at a time and run the app/tests after each hop.
Angular 19 requires Node.js 18.19.1+, 20.11.1+, or 22, and TypeScript 5.5 up to 5.8.
Check your Node.js & TypeScript versions for Angular 19 →Update the core framework and CLI together. This applies the official automatic migration schematics for this version.
ng update @angular/core@19 @angular/cli@19
Components, directives, and pipes are standalone by default; NgModule-based declarations must set standalone: false. Run the standalone migration, and optionally enable strictStandalone.
Incremental hydration (preview), route-level render mode (SSR/SSG/CSR), the experimental resource() API, linkedSignal, @let template variables, and HMR for styles are introduced.
Sources: Angular Update Guide: v18 → v19 · Angular 19.0.0 release notes
Angular 19 → Angular 20
(7 steps)Commit or stash all work, then make sure you are on the latest minor/patch of your current major before running ng update. Upgrade exactly one major at a time and run the app/tests after each hop.
Angular 20 requires Node.js 20.19+, 22.12+, or 24, and TypeScript 5.8 (up to <6.0). Node 18 and TypeScript 5.7 and below are no longer supported.
Check your Node.js & TypeScript versions for Angular 20 →Update the core framework and CLI together. This applies the official automatic migration schematics for this version.
ng update @angular/core@20 @angular/cli@20
The DOCUMENT token moved from @angular/common to @angular/core. The ng update migration rewrites the imports automatically.
The structural directives are deprecated in favor of built-in control flow (@if/@for/@switch). They still ship in Angular 22, marked for removal in a future major. Run the control-flow migration. TestBed.get() is removed (auto-migrated to TestBed.inject()), and TestBed.flushEffects() is deprecated in favor of TestBed.tick().
Convert a template to @if/@for online →ng generate @angular/core:control-flow
The compiler can now type-check host bindings and @HostBinding/@HostListener expressions. It is opt-in in v20 via typeCheckHostBindings in angularCompilerOptions, and becomes the default in v21, so enabling it now surfaces errors early.
effect(), linkedSignal() and toSignal() are now stable, completing the core signal APIs. Zoneless change detection moves to developer preview and provideExperimentalZonelessChangeDetection is renamed provideZonelessChangeDetection.
Sources: Angular Update Guide: v19 → v20 · Angular 20.0.0 release notes · Announcing Angular v20 (Angular Blog)
Angular 20 → Angular 21
(9 steps)Commit or stash all work, then make sure you are on the latest minor/patch of your current major before running ng update. Upgrade exactly one major at a time and run the app/tests after each hop.
Angular 21 requires Node.js 20.19+, 22.12+, or 24, and TypeScript 5.9 (up to <6.0).
Check your Node.js & TypeScript versions for Angular 21 →Update the core framework and CLI together. This applies the official automatic migration schematics for this version.
ng update @angular/core@21 @angular/cli@21
Applications are zoneless unless they provide Zone.js change detection. The ng update migration adds provideZoneChangeDetection() to existing apps so they keep working; review code that relies on Zone.js patching before removing it.
New projects use Vitest. Existing projects keep Karma, which is still supported (new projects can opt in with --test-runner=karma). The experimental Jest and Web Test Runner builders are slated for removal in v22.
Convert Jasmine specs to Vitest online →typeCheckHostBindings is now on by default, so invalid host binding and @HostBinding/@HostListener expressions become compile errors. Fix what the compiler flags, or turn the option off temporarily.
HttpClient is available from the root injector without calling provideHttpClient(). Keep provideHttpClient() when you need interceptors or features such as withFetch().
Angular now recommends native [class] and [style] bindings over NgClass and NgStyle, and provides migrations for both.
ng generate @angular/core:ngclass-to-class
Signal Forms ship as an experimental API — a signal-based alternative to reactive forms. Try it in non-critical areas; it becomes stable in v22.
Sources: Angular Update Guide: v20 → v21 · Angular 21.0.0 release notes · Announcing Angular v21 (Angular Blog)
Angular 21 → Angular 22
(10 steps)Commit or stash all work, then make sure you are on the latest minor/patch of your current major before running ng update. Upgrade exactly one major at a time and run the app/tests after each hop.
Angular 22 requires TypeScript 6.0 (5.9 and below are no longer supported) and Node.js ^22.22.3, ^24.15.0 or ^26.0.0. Node 20 is dropped, and earlier Node 22/24 releases are below the minimum. Upgrade your toolchain before updating.
Check your Node.js & TypeScript versions for Angular 22 →Update the core framework and CLI together. This applies the official automatic migration schematics for this version.
ng update @angular/core@22 @angular/cli@22
A component without changeDetection now uses OnPush, and the old Default strategy is renamed Eager. The ng update migration adds changeDetection: ChangeDetectionStrategy.Eager to existing components, so behavior is preserved. Remove Eager component by component as you move to signals.
Route parameters and data are now inherited from all parent routes by default. There is no migration: set paramsInheritanceStrategy: 'emptyOnly' in withRouterConfig() to keep the old behavior, or review components that read route params/data.
HttpClient now uses fetch instead of XMLHttpRequest. The migration removes withFetch() calls, or adds withXhr() where you need XHR behavior such as upload progress events. reportProgress is deprecated in favor of reportUploadProgress and reportDownloadProgress.
In templates, a?.b now returns undefined instead of null when a is null or undefined, matching TypeScript. The migration wraps affected expressions in $safeNavigationMigration() to keep the old result; check code that compares with === null.
strictTemplates is enabled by default, so stricter template type errors can appear. canMatch guards receive a required currentSnapshot parameter (migrated automatically). The experimental Jest and Web Test Runner builders are removed.
Signal Forms are stable, resource()/rxResource()/httpResource() are production-ready, and the @angular/aria headless accessibility package leaves developer preview.
Reactive Forms → Signal Forms reference →@Service() is a shorter @Injectable({ providedIn: 'root' }) for classes that use inject(). It doesn't support constructor injection, so migrate constructors first, then switch services. @Injectable still works, so this is optional.
Convert constructors to inject() and @Service() online →ng generate @angular/core:inject ng generate @angular/core:service
Sources: Angular Update Guide: v21 → v22 · Angular 22.0.0 release notes · Announcing Angular v22 (Angular Blog)
Tip: Upgrade one major at a time and run ng update for each hop — it applies the official migration schematics automatically. Commit between hops and run your tests. This is a representative checklist of the major changes; always confirm specifics against the official Angular Update Guide for your exact versions.
Upgrading Angular 8 to Angular 22
This plan covers the full path from Angular 8 to Angular 22 — 14 version hops and 83 steps in total. Upgrade one major at a time, running ng update for each hop so the official migration schematics apply. Commit and run your tests between hops.
Breaking changes to check between Angular 8 and Angular 22
- Ivy becomes the default compiler/runtime (Angular 8 → Angular 9): Angular 9 switches to the Ivy rendering engine by default and runs ngcc to compile your dependencies. Expect stricter template type-checking and some changed runtime behavior; you can temporarily opt out with enableIvy: false.
- View Engine is deprecated — Ivy only (Angular 11 → Angular 12): Angular 12 deprecates View Engine; the framework is effectively Ivy-only going forward. Production build becomes the default for ng build, and IE11 support is deprecated.
- View Engine removed and IE11 support dropped (Angular 12 → Angular 13): View Engine is removed from the framework and libraries are now published in Ivy partial-compilation format. Older View Engine libraries still work through ngcc until v16. Internet Explorer 11 support is removed, and string-based loadChildren must use dynamic import().
- Typed Reactive Forms (Angular 13 → Angular 14): FormControl, FormGroup, and FormArray are now strictly typed. Existing forms code may stop compiling; the migration swaps to Untyped* variants so you can adopt typing gradually.
- Angular Material migrates to MDC (Angular 14 → Angular 15): Angular Material components are rebuilt on Material Design Components (MDC). DOM structure and CSS change — audit custom Material styles and run the Material migration. Legacy components are available under @angular/material/legacy-* temporarily.
- ngcc is removed — View Engine libraries no longer work (Angular 15 → Angular 16): The Angular Compatibility Compiler (ngcc) is removed, so any dependency still shipped in View Engine format fails to build. Update or replace those libraries before this hop.
- New esbuild/Vite application builder is the default (Angular 16 → Angular 17): New applications use the esbuild + Vite application builder (@angular-devkit/build-angular:application) with faster builds and a Vite dev server. Existing apps keep the webpack builder until migrated. SSR moves to the new @angular/ssr package and is offered during ng new.
- Standalone is the default (Angular 18 → Angular 19): Components, directives, and pipes are standalone by default; NgModule-based declarations must set standalone: false. Run the standalone migration, and optionally enable strictStandalone.
- Zoneless change detection is the default (Angular 20 → Angular 21): Applications are zoneless unless they provide Zone.js change detection. The ng update migration adds provideZoneChangeDetection() to existing apps so they keep working; review code that relies on Zone.js patching before removing it.
- Vitest replaces Karma as the default test runner (Angular 20 → Angular 21): New projects use Vitest. Existing projects keep Karma, which is still supported (new projects can opt in with --test-runner=karma). The experimental Jest and Web Test Runner builders are slated for removal in v22.
- Host bindings are type-checked by default (Angular 20 → Angular 21): typeCheckHostBindings is now on by default, so invalid host binding and @HostBinding/@HostListener expressions become compile errors. Fix what the compiler flags, or turn the option off temporarily.
- OnPush is the default change detection strategy (Angular 21 → Angular 22): A component without changeDetection now uses OnPush, and the old Default strategy is renamed Eager. The ng update migration adds changeDetection: ChangeDetectionStrategy.Eager to existing components, so behavior is preserved. Remove Eager component by component as you move to signals.
- Route paramsInheritanceStrategy defaults to 'always' (Angular 21 → Angular 22): Route parameters and data are now inherited from all parent routes by default. There is no migration: set paramsInheritanceStrategy: 'emptyOnly' in withRouterConfig() to keep the old behavior, or review components that read route params/data.
- HttpClient uses the Fetch API by default (Angular 21 → Angular 22): HttpClient now uses fetch instead of XMLHttpRequest. The migration removes withFetch() calls, or adds withXhr() where you need XHR behavior such as upload progress events. reportProgress is deprecated in favor of reportUploadProgress and reportDownloadProgress.
- Template optional chaining returns undefined (Angular 21 → Angular 22): In templates, a?.b now returns undefined instead of null when a is null or undefined, matching TypeScript. The migration wraps affected expressions in $safeNavigationMigration() to keep the old result; check code that compares with === null.
Hops in this path
- Angular 8 → Angular 9 — 5 steps
- Angular 9 → Angular 10 — 5 steps
- Angular 10 → Angular 11 — 5 steps
- Angular 11 → Angular 12 — 5 steps
- Angular 12 → Angular 13 — 5 steps
- Angular 13 → Angular 14 — 5 steps
- Angular 14 → Angular 15 — 5 steps
- Angular 15 → Angular 16 — 6 steps
- Angular 16 → Angular 17 — 6 steps
- Angular 17 → Angular 18 — 5 steps
- Angular 18 → Angular 19 — 5 steps
- Angular 19 → Angular 20 — 7 steps
- Angular 20 → Angular 21 — 9 steps
- Angular 21 → Angular 22 — 10 steps
Before you start
- Commit or stash your work and upgrade on a branch so you can roll back.
- Get on the latest minor/patch of Angular 8 before the first hop.
- Update third-party libraries (including Angular Material/CDK) alongside each hop, and run your tests after each one.
Sources
Every step in this plan is checked against Angular's official documentation and release notes. Last reviewed .
- Angular Update Guide: v8 → v9
- Angular 9.0.0 release notes
- Angular Update Guide: v9 → v10
- Angular 10.0.0 release notes
- Angular Update Guide: v10 → v11
- Angular 11.0.0 release notes
- Angular Update Guide: v11 → v12
- Angular 12.0.0 release notes
- Angular Update Guide: v12 → v13
- Angular 13.0.0 release notes
- Angular Update Guide: v13 → v14
- Angular 14.0.0 release notes
- Angular Update Guide: v14 → v15
- Angular 15.0.0 release notes
- Angular Update Guide: v15 → v16
- Angular 16.0.0 release notes
- Angular Update Guide: v16 → v17
- Angular 17.0.0 release notes
- Angular Update Guide: v17 → v18
- Angular 18.0.0 release notes
- Angular Update Guide: v18 → v19
- Angular 19.0.0 release notes
- Angular Update Guide: v19 → v20
- Angular 20.0.0 release notes
- Announcing Angular v20 (Angular Blog)
- Angular Update Guide: v20 → v21
- Angular 21.0.0 release notes
- Announcing Angular v21 (Angular Blog)
- Angular Update Guide: v21 → v22
- Angular 22.0.0 release notes
- Announcing Angular v22 (Angular Blog)
- Angular version compatibility (Node.js, TypeScript, RxJS)
- Angular Update Guide