Wanna see something cool? Check out Angular Spotify 🎧

Upgrade to Angular 20 from Angular 13 - Part 2: Angular 15

Time really flies! It has been almost a month since I last worked on upgrading my Jira Clone from Angular 13 to 14. Since then, I have been to quite a few exciting events:

  • Google I/O Extended MienTrung 2025, where I had the chance to connect with the developer community in Vietnam 🇻🇳
  • SCS Youth Training, where I was a Lead Trainer supporting a group of aspiring Digital Advocates as they prepared to teach digital skills to the public
  • And on top of that, work has been packed with new projects and challenges

But now I’m back to continue our Angular migration journey! In Part 1, we successfully upgraded from Angular 13 to Angular 14, navigating through various dependency conflicts with ESLint, custom webpack configurations, Ant Design packages, and even Sentry integration. We learned some valuable lessons about using --force flags strategically and checking package compatibility with npm view.

Quick Recap: What We Accomplished in Part 1

For those who missed Part 1, here’s what we tackled:

  • Started with Angular 13 and planned the incremental upgrade path: 13 → 14 → 15 → 16 → 17 → 18 → 19 → 20

  • Upgraded to Angular 14 using:

ng update @angular/core@14 @angular/cli@14 --force
  • Resolved dependency conflicts with:

    • @angular-eslint/schematics (upgraded to 14.3.0)
    • @angular-builders/custom-webpack (upgraded to 14.1.0)
    • @ant-design/icons-angular and ng-zorro-antd (upgraded to 14.1.0)
    • @sentry/angular (upgraded to 9.30.0)
  • Fixed build issues by removing the deprecated --sourceMap=true flag

  • Successfully deployed to Netlify with a working Angular 14 application

The key takeaway was that incremental upgrades are the way to go, and it’s perfectly fine to use --force during major version transitions as long as you resolve all dependencies before merging.

The Next Challenge: Angular 14 → 15

Now it’s time to tackle the next step in our migration journey. Please note that for now, I will upgrade the Angular version first before running any schematics for migrating to standalone component and control flow (available in Angular v17).

With the lessons learned from Part 1, the upgrade to Angular 15 should be easier to tackle.

Create a New Branch

First things first, I created a new branch to safely experiment:

git checkout -b trung/v20-migration-part-2

Step 1: ng update

I started with the Angular 15 upgrade:

ng update @angular/core@15 @angular/cli@15

Note: If you see the error zsh: command not found: ng, it means you don’t have the Angular CLI installed globally. You have two options:

  1. Install it globally (recommended for frequent Angular development):

    npm install -g @angular/cli

    Guide: https://angular.dev/installation#install-angular-cli

  2. Use npx (if you prefer not to install globally):

    npx ng update @angular/core@15 @angular/cli@15

The npx command allows you to run an arbitrary command from an npm package (either installed locally or fetched remotely). If ng doesn’t exist on your machine, npm will fetch it from the registry and execute it.

ng update —force

I ran the command and immediately hit an error that looked very familiar from Part 1:

> npx ng update @angular/core@15 @angular/cli@15

The installed Angular CLI version is outdated.
Installing a temporary Angular CLI versioned 15.2.11 to perform the update.
✔ Packages successfully installed.
Using package manager: npm
Collecting installed dependencies...
Found 70 dependencies.
Fetching dependency metadata from registry...
                  Package "@angular-eslint/schematics" has an incompatible peer dependency to "@angular/cli" (requires ">= 14.0.0 < 15.0.0", would install "15.2.11").
✖ Migration failed: Incompatible peer dependencies found.
Peer dependency warnings when installing dependencies means that those dependencies might not work correctly together.
You can use the '--force' option to ignore incompatible peer dependencies and instead address these warnings later.

The issue is that ESLint requires a specific Angular version. We have a chicken-and-egg problem: if we upgrade ESLint first, it will require Angular 14, but if we upgrade Angular first, ESLint will complain. The solution is to use the --force option to proceed with the Angular upgrade first, then upgrade the dependencies.

npx ng update @angular/core@15 @angular/cli@15 --force

After running the command with --force, now all Angular versions are updated to v15.

package.json after upgrading

Step 2: Upgrading @angular-builders/custom-webpack

I committed the changes and tried running npm install, but encountered a compatibility issue:

> npm install

npm error code ERESOLVE
npm error ERESOLVE could not resolve
npm error
npm error While resolving: @angular-builders/[email protected]
npm error Found: @angular/[email protected]
npm error node_modules/@angular/compiler-cli
npm error   dev @angular/compiler-cli@"^15.2.10" from the root project
npm error   peer @angular/compiler-cli@"^15.0.0" from @angular-devkit/[email protected]
npm error   node_modules/@angular-devkit/build-angular
npm error     dev @angular-devkit/build-angular@"^15.2.11" from the root project
npm error     peer @angular-devkit/build-angular@">=0.8.9 || >= 12.0.0" from @storybook/[email protected]
npm error     node_modules/@storybook/angular
npm error       dev @storybook/angular@"^6.1.11" from the root project
npm error       1 more (@storybook/addon-docs)
npm error   2 more (@ngtools/webpack, @storybook/angular)
npm error
npm error Could not resolve dependency:
npm error peer @angular/compiler-cli@"^14.0.0" from @angular-builders/[email protected]
npm error node_modules/@angular-builders/custom-webpack
npm error   dev @angular-builders/custom-webpack@"^14.1.0" from the root project
npm error
npm error Conflicting peer dependency: @angular/[email protected]
npm error node_modules/@angular/compiler-cli
npm error   peer @angular/compiler-cli@"^14.0.0" from @angular-builders/[email protected]
npm error   node_modules/@angular-builders/custom-webpack
npm error     dev @angular-builders/custom-webpack@"^14.1.0" from the root project
npm error
npm error Fix the upstream dependency conflict, or retry
npm error this command with --force or --legacy-peer-deps
npm error to accept an incorrect (and potentially broken) dependency resolution.

This npm error occurs because @angular-builders/[email protected] requires Angular 14’s @angular/compiler-cli, but after upgrading to Angular 15, the project now has Angular 15’s @angular/[email protected], creating a version conflict that npm cannot automatically resolve.

Which means we need to also upgrade @angular-builders/custom-webpack to a newer version.

Upgrading Custom Webpack

To see what versions were available for @angular-builders/custom-webpack, I ran:

> npm view @angular-builders/custom-webpack versions --json

[
  ...
  "14.1.0",
  "15.0.0-beta.0",
+  "15.0.0",
  "16.0.0-beta.0",
  "16.0.0-beta.1",
  "16.0.0-beta.2",
  "16.0.0",
  ...
]

The list was long, but I could use version 15.0.0. To verify compatibility, I checked the peer dependencies:

> npm view @angular-builders/[email protected] peerDependencies --json

{
  "@angular/compiler-cli": "^15.0.0"
}

I updated the package.json to use @angular-builders/[email protected] and ran npm install. For sure, there are still a few dependencies we need to resolve before a normal npm install can run successfully. So I ran npm install --force first to generate a new package-lock.json, committed the changes, and moved on to the next error.

Upgrading Custom Webpack Force

Step 3. Upgrade @angular-eslint/schematics

After running npm install again, I saw that @angular-eslint/schematics also needed an upgrade.

ESLint schematics upgrade

I checked the available versions:

> npm view @angular-eslint/schematics versions --json

"15.2.0",
"15.2.1-alpha.0",
"15.2.1-alpha.2",
"15.2.1-alpha.5",
"15.2.1-alpha.9",
"15.2.1-alpha.13",
"15.2.1-alpha.15",
"15.2.1-alpha.18",
+ "15.2.1"

There were many versions available up to 20, so I picked 15.2.1 and updated my package.json for all @angular-eslint/* packages. After that, I ran:

npm install --force

Committed the changes and moved on — now it’s time to tackle @angular/cdk.

ESLint schematics upgrade

Step 4: Upgrade @angular/cdk

Running npm install again, we can see that @angular/cdk is now not compatible. I guess I forgot to update it in Part 1 but it was still compatible previously.

Upgrade @angular/cdk

We do the very similar process.

> npm view @angular/cdk versions --json

"15.2.0-next.2",
"15.2.0-next.3",
"15.2.0-next.4",
"15.2.0-rc.0",
"15.2.0",
"15.2.1",
"15.2.2",
"15.2.3",
"15.2.4",
"15.2.5",
"15.2.6",
"15.2.7",
"15.2.8",
+ "15.2.9",
"16.0.0-next.0",
"16.0.0-next.1",
"16.0.0-next.2",
"16.0.0-next.3",
"16.0.0-next.4",

There were many versions available up to 20, so I picked 15.2.9 and updated my package.json for all @angular/cdk. After that, I ran npm install --force as not all dependencies had been resolved. Committed the changes.

"dependencies": {
  "@angular/animations": "^15.2.10",
-  "@angular/cdk": "^13.2.4",
+  "@angular/cdk": "^15.2.9",
  "@angular/common": "^15.2.10",
  "@angular/compiler": "^15.2.10",

Step 5: Upgrading Ant Design Packages

Next, @ant-design/icons-angular was not yet compatible.

Ant Design packages upgrade

I followed the same process and checked available versions:

> npm view @ant-design/icons-angular versions --json

"13.1.0",
"14.1.0",
+ "15.0.0",
"16.0.0-beta.0",
"16.0.0",
"17.0.0-beta.0",
"17.0.0",

I chose version 15.0.0 since it’s the closest version that should be compatible with Angular 15. I noticed ng-zorro-antd needed upgrade as well. And surprisingly, after upgrading those two, running npm install did not show any error.

Ant Design versions

Done

Running npm start works perfectly as well ✅ Mission complete.

Ng serve success

The Angular 15 upgrade is complete. Compared to the Angular 14 upgrade, this round was much smoother and faster. Took about an hour, including screenshots and writing this post 🤣

Here is the PR for reference: https://github.com/trungvose/jira-clone-angular/pull/107

See you in Part 3: Angular 16.

✅ Angular 15 is live on PROD!

Merged and deployed successfully. Everything looks good.

Angular 15 is live on PROD!

Published 19 Jul 2025

Read more

 — Upgrade to Angular 20 from Angular 13 - Part 1: Angular 14
 — Typescript this and implement debounce
 — Classnames implementation in TypeScript
 — Validating Python Indentation in TypeScript
 — React Aria Components - Slider with filled background