Wanna see something cool? Check out Angular Spotify 🎧

Upgrade to Angular 20 from Angular 13 - Part 1: Angular 14

Recently, Angular 20 has been released with tons of crazy cool features! While everyone’s talking about the major highlights, one of the less-discussed gems is the improved Angular Devtools that let you see simplified stats directly in Chrome DevTools.

I was super excited to try it out, but instead of starting a fresh Angular 20 app, I thought about the applications I published years ago - Jira Clone, Tetris, and Angular Spotify - that are still running on Angular 10 or so 😂. This is the perfect moment to upgrade them to Angular 20 and then explore all the new features!

So let’s start with migrating my Jira Clone from Angular 13 to Angular 20. Spoiler alert: it’s not as straightforward as I initially thought! 😅

The Upgrade Strategy

Step 1: Create a New Branch

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

git checkout -b trung/v20

Step 2: Plan the Upgrade Path

Angular does an excellent job guiding us through the upgrade process. I visited angular.dev/update-guide and selected version 13 as the starting point (what Jira Clone is currently running) and version 20 as the target.

Initially, I thought Jira Clone was just a simple project that fetches data from a server and renders it on the client side. But the more I thought about it, I realized there were quite a few workarounds I implemented in Angular 13 to make certain features work. For example, I needed a custom webpack configuration to process SCSS files through postcss-loader with several plugins:

{
  test: /\.scss$/,
  loader: 'postcss-loader',
  options: {
    postcssOptions: {
      ident: 'postcss',
      syntax: 'postcss-scss',
      plugins: ['postcss-import', 'tailwindcss', 'autoprefixer'],
    },
  },
}

This meant the upgrade from Angular 13 to Angular 20 might not be as smooth as I initially anticipated. So I chose “Medium” application complexity to get notified about the tricky steps.

Angular 13 to 20 upgrade path

The Reality Check

As you can see from the suggested steps, the safest route is to upgrade incrementally: 13 → 14 → 15 → 16 → 17 → 18 → 19 → 20 😂

In a real production application, you’d plan these upgrades in advance and tackle one version per sprint. But since this is my side project, I’m going to do it all in one weekend morning (that didn’t happen - I only managed to migrate to Angular 14 in one morning and a bit of night time 🤣)

Pro tip: After each upgrade step, test your changes and commit them if everything works. This way, if the next step fails, you can always roll back to the previous working version. Don’t try to do everything at once and commit at the end - you’ll never know which changes worked and which broke the upgrade.

Angular upgrade steps

Step 1: Upgrade to Angular 14

Running the Update Command

I started with the Angular 14 upgrade:

ng update @angular/core@14 @angular/cli@14

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@14 @angular/cli@14

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.

First Roadblock: ESLint Compatibility

I ran the command and immediately hit an error:

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

The installed Angular CLI version is outdated.
Installing a temporary Angular CLI versioned 14.2.13 to perform the update.
✔ Package 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 ">= 13.0.0 < 14.0.0", would install "14.2.13").
✖ 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.

Angular update with force flag

The Custom Webpack Dilemma

After the Angular upgrade, I ran npm start and immediately encountered another error:

This version of CLI is only compatible with Angular versions ^13.0.0 || ^13.3.0-rc.0,
but Angular version 14.3.0 was found instead.

Please visit the link below to find instructions on how to update Angular.
https://update.angular.io/

Angular CLI compatibility error

This was strange because the Angular CLI version was actually 14.2.13. I suspected the issue was with the @angular-devkit versions. Even though @angular-devkit/build-angular was at 14.2.13, other packages like @angular-devkit/core and @angular-devkit/schematics were still at 13.2.5.

To investigate which packages were using different versions of @angular-devkit/build-angular, I ran:

npm ls @angular-devkit/build-angular

The output revealed the culprit:

[email protected] /Users/trung.vo/Source/jira-clone-angular
├─┬ @angular-builders/[email protected]
│ └── @angular-devkit/[email protected]
├── @angular-devkit/[email protected]
└─┬ @storybook/[email protected]
  └── @angular-devkit/[email protected] deduped

The @angular-builders/[email protected] was using @angular-devkit/[email protected], so we needed to upgrade it.

Upgrading Custom Webpack

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

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

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

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

Output:

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

Perfect! We definitely have compiler-cli 14 in our project, so I updated the package.json to use @angular-builders/[email protected].

Custom webpack versions

Upgrading ESLint Schematics

After running npm install again, I saw that @angular-eslint/[email protected] also needed an upgrade.

ESLint schematics upgrade

I checked the available versions:

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

There were many versions available up to 20, so I picked 14.3.0 and updated my package.json.

ESLint schematics upgrade

Upgrading Ant Design Packages

Next, @ant-design/[email protected] was causing issues. I followed the same process and checked available versions:

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

I chose version 14.1.0 since it’s the closest version that should be compatible with Angular 14. I also noticed ng-zorro-antd was on 13.1.0, so I upgraded that as well.

Ant Design packages upgrade

Ant Design versions

The Sentry Challenge

Run npm install again and now @sentry/[email protected] was throwing an error - which was expected! 😄 The tricky part with Sentry is that it doesn’t follow Angular’s versioning pattern (13, 14, etc.). Instead, it uses its own versioning like 6.18.1, so the next version that supports Angular 14 would likely be version 7.

Sentry version issue

I checked the available Sentry versions:

npm view @sentry/angular versions --json

Sentry versions

Wow, there were many versions! Sentry doesn’t jump per major version as you might expect. I searched for @sentry/angular compatible with angular 14 and found comprehensive documentation from Sentry:

https://docs.sentry.io/platforms/javascript/guides/angular/manual-setup/#which-sdk-version-should-you-use-with-your-angular-version

In its current major version, the Sentry Angular SDK supports Angular 14 and newer.

If you’re using an older version of Angular, you also need to use an older version of the SDK. See the table below for compatibility guidance

Sentry compatibility guide

I had two options:

  1. Install the latest version using npm install @sentry/angular@latest --force (we need --force because our dependencies aren’t fully resolved yet due to the Sentry package itself)
  2. Manually pick a compatible version from the npm view output

I chose option 2 and picked version 9.30.0. To be safe, I checked the peer dependencies first:

npm view @sentry/[email protected] peerDependencies --json

Excellent! The peer dependencies were quite broad: >= 14.x <= 20.x, so we were safe to proceed.

Sentry compatibility guide

Pro tip: npm view <package name> peerDependencies --json is the way to verify package dependencies without going to the npm website or “guessing”!

Success at Last!

Finally, npm install worked! I ran npm start and the application finally started building.

npm install success

However, there was still a Sentry error preventing the app from starting:

Sentry error

Since the issue was isolated to Sentry, I temporarily commented out the problematic code. The app compiled successfully!

Angular success

👉 I opened this PR here: https://github.com/trungvose/jira-clone-angular/pull/105

What’s Next?

This was just the first step - upgrading to Angular 14. The journey continues with upgrades to versions 15, 16, 17, 18, 19, and finally 20. Each step will likely bring its own challenges and dependencies to resolve.

The key takeaways from this Angular 14 upgrade:

  • It’s okay to use --force when dealing with peer dependency conflicts during major version upgrades, but make sure to resolve all dependencies before merging to the main branch. Otherwise, CI builds and other developers’ machines will fail to run npm install and they’ll also need to use --force
  • Check package version using npm view <package> versions --json
  • Check package compatibility using npm view <package> peerDependencies --json
  • Upgrade dependencies incrementally and test after each step
  • Don’t be afraid to temporarily comment out problematic code to isolate issues

Stay tuned for the next part where we upgrade Angular 15!

Published 20 Jun 2025

Read more

 — Typescript this and implement debounce
 — Classnames implementation in TypeScript
 — Validating Python Indentation in TypeScript
 — React Aria Components - Slider with filled background
 — Learn Angular Signals by implementing your own