# Updating an Angular application with ng update, one major at a time

Source : https://consignestudio.fr/en/guides/update-angular-ng-update/ · published 2026-10-27 · Antoine Despres, Consigne

A safe Angular update moves one major version at a time, with ng update, on a clean branch with green checks, after aligning Node.js and TypeScript with what the target version requires. Since Angular 22, a major version ships every 12 months and each one is normally supported for 24 months. Angular 20 stops receiving fixes after 28 November 2026.

## Release cadence and support windows

Angular now announces **one major version every 12 months**, with four to six minor releases per major. Until Angular 22 the cycle was six months. Each major is normally supported for **24 months**: 12 months of active support, then 12 months of long-term support (LTS), which only receives critical fixes and security patches.

The versions still supported on 27 October 2026, according to angular.dev:

| Version | Released | Active support ends | LTS ends |
|---|---|---|---|
| Angular 22 | 3 June 2026 | June 2027 | June 2028 |
| Angular 21 | 19 November 2025 | 3 June 2026 | June 2027 |
| Angular 20 | 28 May 2025 | 19 November 2025 | **28 November 2026** |

Versions 2 to 19 are no longer supported. Angular 23 is expected around June 2027; angular.dev notes that all future dates are approximate. Versions released under the old cycle had shorter support: Angular 20 will have been supported for 18 months.

> An application on Angular 20 has about one month of security fixes left. The sensible target is at least Angular 21, and Angular 22 if you want to stay covered until mid-2028.

## The rule: one major at a time

angular.dev sets two conditions for `ng update`: the target version must be supported, and your current version must be **within one major** of the target. To go from 19 to 21, you go through 20.

This is not a formality. `ng update` runs **automatic migrations** (schematics) that rewrite your code for the next version. They are written to chain from one major to the next, hence the rule. If you edit the version numbers in `package.json` and run `npm install`, no migration runs at all.

## Before you run ng update

1. **A clean Git working tree.** By default `ng update` refuses to run when the repository contains modified or untracked files. The `--allow-dirty` option removes that safeguard; avoid it. Work on a dedicated branch.
2. **Green checks**: lint, unit tests, production build, and end-to-end tests if you have them. Without a green baseline you cannot tell whether a failure comes from the update.
3. **Node.js and TypeScript** at the versions the target requires, per the angular.dev compatibility table:

| Angular | Node.js | TypeScript |
|---|---|---|
| 20.2 and 20.3 | ^20.19.0, ^22.12.0 or ^24.0.0 | 5.8 to 5.9 |
| 21 | ^20.19.0, ^22.12.0 or ^24.0.0 | 5.9 |
| 22 | ^22.22.3, ^24.15.0 or ^26.0.0 | 6.0 |

Angular 22 drops Node.js 20. Remember the image of your CI agents, your build containers and the developers' machines.

4. **The official guide** for your jump: the Update Guide on angular.dev generates the list of changes to make from your current version, your target version and the complexity of your application.

## The steps for one major jump

Example, from Angular 20 to 21:

```bash
git switch -c upgrade/angular-21
npx ng update @angular/core@21 @angular/cli@21 --create-commits
```

`--create-commits` creates a commit for each update and each migration. Review is easier, and you can revert one specific migration.

Then, in this order:

1. **Packages that follow Angular**: `ng update @angular/material@21` if you use Material and the CDK, then the tooling, for example `ng update angular-eslint`.
2. **Third-party libraries**: each one needs a release compatible with the new major (see below).
3. **The checks**: types, lint, tests, build, end-to-end tests. Fix them in that order, because one type error often causes a cascade of failures further down.
4. **Dependencies**: review `npm audit` and the `overrides` section of `package.json`. An override added for an old vulnerability may have become useless, or may now block a resolution.
5. **Merge**, then start the next jump if you are aiming further. Do not stack two majors in a single merge request.

Minor and patch updates can be done at any time between majors, with the same checks.

## The most common traps

### Third-party libraries that block

This is the most frequent reason an `ng update` fails on peer dependencies: a component library requires the CDK of the same major, a state library requires the same Angular version. Before you start, check that each library has a release compatible with the target. If it does, update it in the **same command** as the framework so peer dependencies resolve together:

```bash
npx ng update @angular/core@21 @angular/cli@21 @ngrx/store
```

If a library has no compatible release yet, wait for it or replace it. Forcing only moves the error to runtime.

### The --force option

`--force` ignores peer dependency version mismatches. It makes the command succeed, not the application: a library built for the previous major can break at compile time or, worse, at runtime. Keep it for cases where you know exactly why the conflict is harmless.

### Migrations that never ran

If someone already bumped the packages by hand, the migrations can be run on their own:

```bash
npx ng update @angular/core --migrate-only --from=20 --to=21
```

`--from` and `--to` only work with `--migrate-only`, and only for a single package.

### Node.js, npm and CI

An update that passes locally and fails in CI almost always comes down to a different Node.js version. Pin the version (an `.nvmrc` file, the `engines` field, the CI image) in the same branch as the update. On the npm side, a `Cannot read properties of null (reading 'edgesOut')` error has been observed with npm 10 during a move to Angular 21; upgrading to npm 11 resolved it.

### Accumulated deprecations

A deprecated API stays available for at least the next major release, roughly 12 months, and is only removed in a major. Deal with deprecation warnings at each jump: they are the compile errors of the next one.

## Planning maintenance over time

With one major a year and 24 months of support, an application updated once a year always stays on a supported version. The risk comes from falling behind: the more majors you have to catch up, the more third-party libraries diverge and the more each jump costs. Put the major upgrade on the calendar when a new major ships, and apply minor releases as they come.

A short checklist for each jump:

| Step | Done when |
|---|---|
| Baseline | branch created, working tree clean, all checks green |
| Environment | Node.js and TypeScript match the compatibility table, CI image updated |
| Framework | `ng update` for core and CLI with `--create-commits` |
| Ecosystem | Material, CDK, ESLint tooling and third-party libraries updated |
| Verification | types, lint, tests, build and end-to-end tests green again |
| Clean-up | `npm audit` reviewed, obsolete overrides removed, deprecations handled |

## Starting a new project on Angular 22

If you are starting a new application rather than updating one, [Socle](https://consignestudio.fr/en/angular-starter/) is an Angular 22 starter (zoneless, signals, standalone components) whose `npm run verify` command chains 13 checks, including lint, strict typing, unit and end-to-end tests, build budgets, accessibility and dependency audit. Its upgrading guide follows the procedure above and relies on those checks to show what an update broke. It does not update an existing application, has no back end, and requires Node.js 22.22.3 or later, or Node.js 24.

## Sources

- [angular.dev, Angular versioning and releases](https://angular.dev/reference/releases)
- [angular.dev, Version compatibility](https://angular.dev/reference/versions)
- [angular.dev, ng update](https://angular.dev/cli/update)
- [angular.dev, Update Guide](https://angular.dev/update-guide)
- Socle, upgrading guide (docs/upgrading.md)
- Pages checked on 2026-10-27
