The task of upgrading Jira Clone to Angular 20 has been sitting on my backlog forever. If you have been following this series, you know the drill. In Part 1 we went from Angular 13 to 14, and in Part 2 we tackled Angular 14 to 15. Each time, the process was mostly the same: run ng update, hit dependency conflicts, resolve them one by one, test, and commit.
It is usually tedious to do those migrations manually. But this time, I tried something different. I used Claude Code to do the whole thing.
I had two detailed blog posts from the previous migrations (Part 1 and Part 2) that documented every step, every error, and every resolution. That is a lot of context. So I thought, what if I just ask Claude to read those posts, understand the pattern, and generate a plan for the Angular 16 upgrade?
I used the superpower workflow to generate a detailed implementation plan.
Claude read through both previous posts, understood the proven pattern (upgrade Angular core first with --force, then resolve each dependency conflict one at a time), and produced a comprehensive 14-task plan.
After just a few minutes, the plan was ready. I read through all of it. Looked good.
Here is a summary of the steps Claude generated:
trung/v20-migration-part-3--force (same ESLint chicken-and-egg problem as before)~4.8.4 to ~5.0.4 (Angular 16 requires TS 5.0+)~0.11.4 to ~0.13.0 (significant jump)16.0.016.3.116.2.14ng-zorro-antd to 16.2.2, @ant-design/icons-angular to 16.0.0)16.1.2 to 22.1.1 (this was the biggest risk, major version jump)7.0.0Claude also identified the key changes in Angular 16 (Signals in developer preview, TypeScript 5.0 support, zone.js bump) and listed potential gotchas, including the ngx-quill major version jump from 16 to 22 since ngx-quill uses its own versioning that does not follow Angular’s.
The full plan is available in the repo.
Once I reviewed the plan, I kicked off the execution. Claude worked through each task sequentially, following the exact same pattern we established in Parts 1 and 2:
package.jsonnpm install --force (since not all dependencies are resolved yet)npm view <package>@<version> peerDependencies --jsonThe whole process ran for about 20 minutes. I mostly just watched and approved the commands. There was one moment where Claude needed to resolve an unexpected issue with ngx-quill’s API changes, but it handled that by searching the codebase for quill usage and checking compatibility.
After all 14 tasks completed, I ran npm start and things worked as expected. The application compiled and served without errors. Board view, issue detail, drag and drop, everything functioned correctly.
Here is the dependency version map for reference:
| Package | Before (v15) | After (v16) |
|---|---|---|
@angular/core |
^15.2.10 |
^16.2.12 |
@angular/cli |
^15.2.11 |
^16.2.14 |
typescript |
~4.8.4 |
~5.0.4 |
zone.js |
~0.11.4 |
~0.13.0 |
ng-zorro-antd |
^15.0.0 |
^16.2.2 |
ngx-quill |
^16.1.2 |
^22.1.1 |
@angular/cdk |
^15.2.9 |
^16.2.14 |
No code changes were needed beyond the dependency upgrades. Angular 16 introduces Signals in developer preview, but there is no migration needed yet. Standalone components and control flow syntax migration are deferred to the Angular 17 step.
https://github.com/trungvose/jira-clone-angular/pull/109
Doing the first two migrations manually and documenting them thoroughly turned out to be the best investment. Those blog posts became the training data for Claude to understand the exact pattern and replicate it. The third migration took about 30 minutes total: 10 minutes of prompting and reviewing the plan, then a single execution run by Claude. What used to be an hour of hands-on work became mostly watching and approving.
The key is that the pattern was well-established:
--force for the initial ng update to bypass the ESLint peer dependency conflictnpm view to check versions and peer dependenciesng serve and ng build since production builds are stricterIf you have repetitive tasks with a clear pattern, documenting the first few iterations thoroughly and then handing it off to AI is a solid approach.
We are at Angular 16 now. The remaining path is 16 -> 17 -> 18 -> 19 -> 20. Angular 17 is going to be the interesting one since that is where standalone components and the new control flow syntax (@if, @for, @switch) become the default. That will require actual code changes, not just dependency bumps.
See you in Part 4.