Carlos Cifuentes
Angular versions · Upgrade strategy

How to upgrade an Angular app that is many versions behind

An app on Angular 9, 12 or 15 does not reach the current version with one command. This is the order of work that keeps it releasable at every step.

By Carlos Cifuentes · Frontend architect · Updated 2026-10-02

One major at a time, or one jump?

The official update policy is explicit: ng update supports moving from one major to the next, and an update across several majors is done one major at a time.

The reason is the migrations. Each major ships code transformations that only run at that step. Examples: the typed forms migration in v14, standalone: false in v19, provideZoneChangeDetection() in v21 and ChangeDetectionStrategy.Eager in v22. Skipping a major skips its migrations, and you fix by hand what the tool would have rewritten.

The alternative is to create a new workspace on the current version and move the code into it. That means fixing every breaking change by hand, all at once. It can work for a small app. For a larger one, compare the options in Rewrite, hybrid or micro-frontends.

Dependency blockers

These ranges come from the official version compatibility table.

AngularNode.jsTypeScript
9 to 1110.13 or 12.113.6 to 4.1
1212.14 or 14.154.2 to 4.3
1312.20, 14.15 or 16.104.4 to 4.6
1414.15 or 16.104.6 to 4.8
1514.20, 16.13 or 18.104.8 to 4.9
1616.14 or 18.104.9.3 to 5.1
1718.13 or 20.95.2 to 5.4
18 to 1918.19, 20.11 or 225.4 to 5.8
20 to 2120.19, 22.12 or 245.8 to 5.9
2222.22.3, 24.15 or 266.0
  • Node.js and TypeScript. Local machines, CI images and build servers move with the framework, and each compiler upgrade can bring new type errors.
  • RxJS. Angular 9 to 12.1 require RxJS 6. From v13 the accepted range is ^6.5.3 || ^7.4.0, and it is still the range in v22. The move to RxJS 7 can be its own step.
  • Angular Material. Update it with the matching major. Plan a visual review at v15, when the components moved to MDC, and at v17, when the legacy components left the package.
  • NgRx. Each NgRx major requires the matching Angular major and ships its own ng update migrations, so it moves in the same hop.
  • View Engine libraries. They worked through ngcc until v15. Angular 16 removed ngcc. Find these libraries early and replace them.
  • Tooling and browsers. TSLint was deprecated in v11. IE11 support ends with v12. The Protractor builder was removed in v19. The webpack-based builders are deprecated in v22.

Build the test safety net first

  • Write end-to-end smoke tests for the critical flows before the first hop, in a tool that does not depend on the Angular version.
  • Keep the unit tests green at every hop. Expect fixes in the tests at v13 (TestBed teardown) and from v18 to v21 (change detection and error handling).
  • Run build, lint and tests in CI for every hop, so a failure points to one major.

The order of work

  1. Inventory the Angular version, Node.js, TypeScript, every library and its supported Angular range.
  2. Delete dead code and unused dependencies.
  3. Put the safety net in place.
  4. For each major: latest patch, ng update for core and CLI, then Material, NgRx and other libraries. Fix, test, commit.
  5. Release at checkpoints where the app is stable. A production release for every major is optional.
  6. Leave optional migrations (standalone, control flow, signals, application builder) for after the app is on a supported version.

Area by area with micro-frontends

In a micro-frontend setup a host composes applications that are built and deployed separately, so the upgrade can go area by area: one team upgrades and releases its area while the others keep working.

There is a condition. If the micro-frontends share a single Angular instance at runtime, they must agree on the version and the upgrade stops being independent. For independent upgrades each micro-frontend carries its own copy of the framework, which costs bundle size, and shared libraries such as the design system must support every Angular version in use. This pays off when several teams own separate areas. For one team it adds cost.

When it is worth getting help

Help is worth it when the app is several majors behind, when it has little test coverage, when key libraries have no upgrade path, or when the team cannot stop feature work. If AngularJS code is still in the product, that part follows a different path: see AngularJS migration. The support dates are in Angular version support and end of life.

More in this section

Planning a migration or a micro-frontend platform?

In a 20-minute call you describe your situation and I tell you how I'd approach it. If it isn't worth doing yet, I'll say so.

Message me on LinkedIn