The Angular team puts a reasonable amount of effort into ensuring major versions have a stable semi-automated migration path and reduced number of breaking changes. However, upgrading involves more than just Angular. An upgrade typically includes upgrades of dependencies like webpack and TypeScript which can have breaking changes of their own. Additionally, new versions can break peer dependencies of packages not depended on by Angular, like TypeScript ESLint. This guide supplements the official update guide with more detailed steps defining the overall process and recommendations for troubleshooting. It is tested as of Angular 14.
Prerequisites
1. Read the documentation on the “Angular versioning and releases”.
- Releases use semantic versioning. Breaking changes will only be introduced in major versions. [i]
- When updating multiple major versions, perform each update one major version at a time. [i]
- A new major version is released every six months. [i]
- Major releases are under active development for six months. After six months, major versions are supported for 12 months. [i]
- Deprecations are enforced three major releases after they are announced. [i]
- Do not extend public API’s that are not explicitly documented as extendable. Do not depend on private API’s. [i]
2. The most common point of failure when performing an upgrade is npm peer dependency resolution failure. Note which packages that have been added to a workspace have peer dependencies on Angular, Angular Material, TypeScript, RxJS, etc. Common examples include @typescript-eslint
, @angular-eslint
, and NgRx. Also, note any additional peer dependencies of these packages, e.g. @typescript-eslint/eslint-plugin
depends on eslint
.
- TypeScript ESlint does not have an explicit dependency on TypeScript. That is defined in its documentation.
- Angular ESLint aligns its major version with Angular.
- NgRx has update guides.
Upgrading Multiple Versions
When upgrading across multiple major versions, upgrade in lockstep but all at once so that builds and tests are only addressed once - with the lastest version.
Upgrade Steps
The ng update
commands in steps 4 and 6 are required to perform automatic migrations. Migrations can be run independently with the –migrations-only option.
- (Optional) Identify compatible versions for packages from prerequisite 2, and update them in
package.json
. See npm error 2 for other solutions.- This is not always required. Angular is generally forward compatible for two major versions. However, that is not always the case, so updating packages with peer dependencies is sometimes required.
- (Recommended) Delete
package-lock.json
. See npm error 1. - If the workspace has libraries, update the peer dependency versions, including Angular but not Material, in each library’s
package.json
. See npm error 3. - Perform step one of the update guide.
- By default, this step requires a clean branch. Use the
--allow-dirty
option to allow updates when the repository contains modified files. - If this step fails with an npm error, find a solution in the npm Errors section.
- By default, this step requires a clean branch. Use the
- If the workspace has libraries that use Angular Material, update the peer dependency versions in each library’s
package.json
. See npm error 4. - If the workspace uses Angular Material, perform step two of the update guide. Check “I use Angular Material”.
- If this step fails with an npm error, find a solution in the npm Errors section.
- Enumerate the remaining items in the update guide. Evaluate if each applies to the workspace.
- If appropriate, update the lib option in
tsconfig.json
to enable new features. - If a command in step 4 or 6 has been forced, delete
package-lock.json
, and runnpm install
to generate a proper lock file.
npm Errors
When a peer dependency error occurs in step 4 or 6 npm will have deleted node_modules
. Revert any changes to package.json
, and run npm install
.
1. Peer resolution fails to resolve satisfiable @angular-devkit
dependencies.
Resolution:
A. Delete package-lock.json
.
B. Delete node_modules
.
Example
npm ERR! While resolving: ni-systemlink-shared@1.0.0
npm ERR! Found: @angular-devkit/build-angular@12.2.17
npm ERR! node_modules/@angular-devkit/build-angular
npm ERR! dev @angular-devkit/build-angular@"^13.3.9" from the root project
npm ERR! peer @angular-devkit/build-angular@">=0.8.9 || >= 12.0.0" from @storybook/angular@6.5.9
npm ERR! node_modules/@storybook/angular
npm ERR! dev @storybook/angular@"^6.4.19" from the root project
npm ERR!
npm ERR! Could not resolve dependency:
npm ERR! dev @angular-devkit/build-angular@"^13.3.9" from the root project
npm ERR!
npm ERR! Conflicting peer dependency: @angular/compiler-cli@13.3.11
npm ERR! node_modules/@angular/compiler-cli
npm ERR! peer @angular/compiler-cli@"^13.0.0 || ^13.3.0-rc.0" from @angular-devkit/build-angular@13.3.9
npm ERR! node_modules/@angular-devkit/build-angular
npm ERR! dev @angular-devkit/build-angular@"^13.3.9" from the root project
2. Peer resolution fails with a legitimate unsatisfiable error. This will be caused by packages from prerequisite 2.
Resolution:
A. Update the dependency in package.json
with a compatible version before performing step 4.
B. Include the package and a compatible version in the command in step 4.
C. Install the package with a compatible version using the force option option before performing step 4.
D. Use the force option with the command in step 4.
Example
npm ERR! While resolving: ni-systemlink-shared@1.0.0
npm ERR! Found: @angular/common@13.3.11
npm ERR! node_modules/@angular/common
npm ERR! @angular/common@"^13.3.11" from the root project
npm ERR!
npm ERR! Could not resolve dependency:
npm ERR! peer @angular/common@"^12.1.0" from @ni/nimble-angular@10.0.0
npm ERR! node_modules/@ni/nimble-angular
npm ERR! @ni/nimble-angular@"^10.0.0" from the root project
3. Peer resolution fails to resolve a peer dependency of a library in the workspace. The workspace has a library package.json
that declares the old version of a peer dependency.
Resolution: Complete step 3.
Example
npm ERR! While resolving: @ni-kismet/file-manager-lib@1.8.2
npm ERR! Found: @angular/common@13.3.11
npm ERR! node_modules/@angular/common
npm ERR! peer @angular/common@"^13.3.11" from @ni-kismet/file-manager-lib@1.8.2
npm ERR! projects/file-manager-lib
npm ERR! @ni-kismet/file-manager-lib@1.8.2
npm ERR! node_modules/@ni-kismet/file-manager-lib
npm ERR! workspace projects\file-manager-lib from the root project
npm ERR!
npm ERR! Could not resolve dependency:
npm ERR! peer @angular/common@"^12.1.0" from @ni/nimble-angular@10.0.0
npm ERR! node_modules/@ni/nimble-angular
npm ERR! peer @ni/nimble-angular@"^10.0.0" from @ni-kismet/file-manager-lib@1.8.2
npm ERR! projects/file-manager-lib
npm ERR! @ni-kismet/file-manager-lib@1.8.2
npm ERR! node_modules/@ni-kismet/file-manager-lib
npm ERR! workspace projects\file-manager-lib from the root project
```
4. Peer resolution fails to resolve an Angular Material peer of a library in the workspace. Material was incorrectly updated in step 3, or the library’s package.json
was not updated in step 4.
Resolution:
- In step 3, don’t update Material peers.
- Complete step 4.
Example
npm WARN While resolving: @ni-kismet/file-manager-lib@1.8.2
npm WARN Found: @angular/cdk@12.2.13
npm WARN node_modules/@angular/cdk
npm WARN @angular/cdk@"^12.2.13" from the root project
npm WARN 2 more (@angular/material, smart-webcomponents-angular)
npm WARN
npm WARN Could not resolve dependency:
npm WARN peer @angular/cdk@"12.2.13" from @angular/material@12.2.13
npm WARN node_modules/@angular/material
npm WARN @angular/material@"^12.2.13" from the root project
npm WARN ERESOLVE overriding peer dependency
npm WARN While resolving: @ni-kismet/file-manager-lib@1.8.2
npm WARN Found: @angular/cdk@undefined
npm WARN node_modules/@angular/cdk
npm WARN @angular/cdk@"^12.2.13" from the root project
npm WARN
npm WARN Could not resolve dependency:
npm WARN peer @angular/cdk@"^13.3.11" from @ni-kismet/file-manager-lib@1.8.2
npm WARN projects/file-manager-lib
npm WARN @ni-kismet/file-manager-lib@1.8.2
npm WARN node_modules/@ni-kismet/file-manager-lib
npm WARN ERESOLVE overriding peer dependency
npm WARN While resolving: @ni-kismet/file-manager-lib@1.8.2
npm WARN Found: @angular/material@undefined
npm WARN node_modules/@angular/material
npm WARN @angular/material@"^12.2.13" from the root project
npm WARN
npm WARN Could not resolve dependency:
npm WARN peer @angular/material@"^13.3.11" from @ni-kismet/file-manager-lib@1.8.2
npm WARN projects/file-manager-lib
npm WARN @ni-kismet/file-manager-lib@1.8.2
npm WARN node_modules/@ni-kismet/file-manager-lib
npm WARN ERESOLVE overriding peer dependency
npm WARN While resolving: @ni-kismet/systemlink-lib-angular@34.0.0
npm WARN Found: @angular/cdk@undefined
npm WARN node_modules/@angular/cdk
npm WARN @angular/cdk@"^12.2.13" from the root project
5. Peer resolution fails because a dependency declares multiple compatible versions for a peer, and npm resolves to the wrong version.
Resolution:
A. Download and modify the package’s package.json
to declare the correct version. Install by file path, and then replace with the correct version.
B. Use the force option with the command in the failing step.
Example
npm ERR! While resolving: ni-systemlink-shared@1.0.0
npm ERR! Found: @angular/cli@13.3.9
npm ERR! node_modules/@angular/cli
npm ERR! dev @angular/cli@"^13.3.9" from the root project
npm ERR!
npm ERR! Could not resolve dependency:
npm ERR! peer @angular/cli@">= 14.0.0 < 15.0.0" from @angular-eslint/schematics@14.1.2
npm ERR! node_modules/@angular-eslint/schematics
npm ERR! peer @angular-eslint/schematics@"^13.5.0 || ^14.1.2" from @ni/eslint-config-angular@3.3.1
npm ERR! node_modules/@ni/eslint-config-angular
npm ERR! dev @ni/eslint-config-angular@"file:./packages/ni-eslint-config-angular-3.3.1.tgz" from the root project
6. Package installation fails stating that a package is not a dependency. The package has been deleted from node_modules
.
Resolution: Reinstall the package by running npm install --no-save <package-name>@<old-version>
.
Example
Package '@angular/core' is not a dependency.
7. Package installation fails stating that an Angular package is already up-to-date. The new version is already installed.
Resolution: Install the old version by running npm install --no-save <package-name>@<old-version>
.
Example
Package '@angular/core' is already up to date.
8. An npm error continues to occur with a dependency declared by file reference. Dependencies declared by file reference fail to install properly if the package is updated, but its version hasn’t changed.
Resolution: Delete package-lock.json
, and run npm install
.
Deleting node_modules
Deleting the node_modules
directory with the right-click menu on Windows is terribly slow. Create a deldir.bat
script with the following to delete directories ~3 times faster.
del /f/s/q %1 > nul
rmdir /s/q %1
Node.js and TypeScript Support
Angular supports LTS and maintenance versions of Node.js and will upgrade TypeScript. As of Angular 15, these versions are officially documented.