Do you also hate upgrading Angular versions? Because I do. I maintain a few open-source projects, and upgrading Angular is probably my least favori...
For further actions, you may consider blocking this person and/or reporting abuse
The
npm cifailure is the part that makes this interesting. An AI agent can migrate Angular APIs correctly and still miss the contract between the lockfile, peer dependencies, and the publishing environment.For example, in a library migrating from Angular 17 to 18, updating
@angular/coreand@angular/compiler-cliisn't enough if@angular-devkit/build-angular, the TypeScript version, and the library'speerDependenciesstill target incompatible ranges. The app may compile locally because of an existingnode_modulestree, then fail in CI with a clean install or break consumers installing the published package. I'd make the skill validate those dependency constraints, runnpm cifrom a clean checkout, build the library in production mode, and test the packed tarball in a separate Angular consumer project. That last step catches problems a successful workspace build can easily miss.Good points. Actually, that first
npm cifailure is exactly why I added clean-install validation to the skill. It creates a fresh temporary copy withoutnode_modules, so it doesn't rely on existing dependencies.I also tested it on a published Angular library with its own demo application. The skill upgraded Angular, I tested the demo, and then published the updated library.
Testing the packed package in a separate consumer project makes sense for library release validation, but I'd say that's beyond the scope of a general Angular upgrade skill. π
That makes sense. Testing the demo app is a much better signal than just checking whether the library builds after the upgrade. One edge case I'd still watch for is Angular's partial-Ivy compatibility and peer dependency ranges. For example, a library can work perfectly in its own demo while its published
peerDependenciesaccidentally exclude an Angular version that should be supported, or while its packaging configuration omits a secondary entry point. Those are release-contract issues rather than upgrade failures, though, so I agree they don't necessarily belong in the core skill. Keeping the upgrade workflow focused and leaving deeper package-release checks as an optional step sounds like the right boundary.Yes, I agree, thanks for the detailed feedback and suggestions.
The part I'd steal is that each fix came from a real failure. The part I'd worry about is the trim from 1,252 to 701 words.
When I've cut agent instructions down, the line that goes first is usually the one that looks redundant but was there because of one specific bad day. Something like "run npm ci before calling it done" reads like filler six weeks later.
Do you keep the three failures (lockfile drift, the npm version for trusted publishing, the big migration jump) as a checklist the skill has to pass after every edit? Otherwise the next "make it shorter" pass might quietly delete one of them.
Good question. Actually, both frontend upgrades were done using the final, shorter version of the skill:
The library upgrade, angular-mydatepicker PR #12, was done before I shortened the instructions. That was actually the project where I originally built and refined the skill based on those failures.
So the shorter version has been tested on real projects, but you're right that this doesn't guarantee every original edge case is still covered. Keeping a regression checklist for future changes is actually a good idea.
That's a better test than my worry: two real upgrades on the short version. If a third one ever breaks, the regression checklist doubles as a record of what the trim dropped, which is the part I'd most want to see. Nice PRs.
The most valuable part of this workflow is that the skill improved after each real failure. Iβd take that one step further by making the validation environment reproducible: pin the Node.js and npm versions, start from a clean checkout, and run the same checks locally and in CI. Otherwise, the agent may fix the symptom in one environment without identifying the underlying version mismatch. It could also record which checks passed and which remain unverified, so βupgrade completeβ means more than a successful build. That turns the skill from a migration script into a repeatable maintenance process that can be trusted across projects.
Thanks for the ideas! That's actually how I approached it. The skill prefers the latest Node.js LTS compatible with the target Angular version and project requirements, rather than pinning a specific version for every project.
It also checks the CI configuration for the npm version, runs
npm ciin a fresh temporary directory withoutnode_modules, and reports which validation steps passed or couldn't be verified.Oh, this is something I should probably send to the team maintaining the Angular component library we're forced to use! π Upgrading Angular itself is already a pain in the ass, but upgrading that library is a whole new level of nightmare! I swear, sometimes I think they assume nobody ever upgrades it, because they make changes like renaming (close) to (closeDialog) between versions, only to rename it back to (close) in the next one. π So yeah, let them give it a try and burn some tokens! π
Nice,
(close)to(closeDialog)and then back to(close)? That sounds like pure evil! πππSo what you actually need is a separate skill for upgrading that specific library?! π€£
Exactly! π Every time we upgrade that library, we joke that they're doing it on purpose, just to make sure we'll have jobs for the rest of our lives! π€£
Great post about agent skills! You are a great developer who succeeded in updating Angular using skills. π I am using my handmade skills and keep updating it to write my AI Avatar README, but it always fails even though AI Avatar is already at v25. π€£
Haha, the struggle of keeping AI skills up to date is real! ππ Turning a repetitive Angular upgrade into a one-week achievement is genuinely impressive. Itβs fascinating how the right skills can transform AI from a coding assistant into a reliable workflow partner. Now Iβm curiousβwhat do you think made the biggest difference: the skillβs instructions, the workflow, or the way you guided the agent? π€π
Thanks! I'd say the workflow, especially the validation steps. Clear instructions are important, but they don't guarantee the agent will get everything right. The first version looked promising, but then
npm cifailed in CI. That's when I realized the skill needed better validation.So I think the biggest difference came from testing it on real projects, finding what failed, and improving the skill along the way.
Thanks! π Haha, sounds like your README skill is giving you more trouble than my Angular upgrades! π€£
Haha, fair enough! π€£ At least both teach us patience and keep us humble. Thanks for the fun discussion, and best of luck with your next upgrade! π
Great job!
π€£π€£
π€£π€£
Of course @sylwia-lask π
hahahahahahahha πππ
@gramli Fair - and I would narrow my claim: the skill should not enforce its own pins, but it can enforce the project's declared requirement. Read engines / .nvmrc / packageManager from the repo, check the running Node/npm against it as a preflight, and fail with "this project requires Node X, you have Y". No pin injection, but the constraint is read from the project and surfaced early. That was the actual point of engine-strict: it turns an opaque E404 from trusted publishing into a named, early failure - and the version mismatch stops being a supply-chain mystery.
Ah, I see what you mean now. The skill already checks the project's Node/npm requirements, but making version mismatches an explicit preflight failure with a clear error message is a good point.
Thanks for clarifying!
The interesting part is that the upgrade itself wasnβt the hardest problem. It was catching the things that only show up outside the local environment. Adding
npm cias a validation step seems like a small change, but it can save a lot of debugging later.One validation I'd add from bitter experience with
ng update: after the migration schematics run,git diff --statalone hides which schematics actually fired. I've had a schematic silently not apply because a version gate was missed, and the diff just looked 'fine' until runtime. I now make agents record the executed migrations (a small log on the upgrade branch works) so the reviewer sees 'which codemods ran', not just the resulting diff. Pairs well with your clean-install check β one verifies the environment, the other verifies the migration actually happened.Good point. The skill already tracks migration commands and milestones during the upgrade and includes migration evidence in the final report.
But youβre right, thatβs not necessarily the same as recording exactly which schematics were executed. Having that information available for PR reviews could be really useful, especially when upgrading across multiple Angular versions.
Thanks for the suggestion!
making npm ci a hard gate before the agent can say done is the best move in here. most agent upgrade failures i have seen are the agent grading its own work on a dev server that is already warm. a clean install plus a production build in a fresh container catches lockfile drift, peer dep conflicts and node version mismatches in one shot.
the 1,252 to 701 word trim tracks with what we saw too, the long instructions were mostly hedging and the validation steps were the part that survived.
did the skill ever stall on the 19 to 22 jump, or did it step one major at a time?
For the 19 β 22 upgrade, I let the agent handle the process automatically. The skill is designed to upgrade one major version at a time, completing the required migrations and validation before advancing.
I didn't manually verify each intermediate version myself, though.
one major at a time with validation between each hop is the right shape. the failure i would watch for is a schematic that silently skips on hop two while the build stays green, so hop three inherits the gap. we log which migrations actually ran per hop so a reviewer can see it.
did the 19 to 22 run leave you a per hop record, or only the final report?
Love that every fix came from a real failure instead of guessing upfront. βWorks locallyβ being the agentβs idea of done is so relatable π Curious how the skill holds up when Angular 23 drops, since thatβll be the real test. Bookmarking this for my next upgrade!
The npm ci step as part of the skill's definition-of-done is the real fix here - you moved the failure from CI (after the push) into the agent's loop (before the push). That pattern generalizes: anything that currently only runs in CI should be runnable locally by the agent, otherwise "works on my machine" just becomes "the agent says it works on my machine".
One addition that has helped me with toolchain-dependent failures: pin the environment explicitly (.nvmrc plus engines and engine-strict=true), so a Node/npm version mismatch surfaces as a clear preflight error instead of an opaque E404 from trusted publishing.
Also +1 on trimming the skill to 701 words - it is cheaper, but the bigger win is that shorter instructions leave less room for the model to paraphrase a validation step into something weaker.
Thanks! I like the idea of catching version mismatches early. But since the skill is meant to work across different Angular projects, I'd rather have it respect each project's existing Node/npm requirements than enforce specific version pins automatically.
What did the upgrade cost you before the vibe coding, and did it stay fixed on a second run? I want the numbers, because an upgrade that passes once and then fails on the next run is worse than the upgrade you were avoiding. If the generated migration gets you across but you can't say why it worked, the next version puts you back in the same chair. I will read where it gave up and you went back to doing it by hand, because that boundary tells me more than a clean run does.
Thatβs actually what most of the article is about.
I maintain four small open-source projects: two Angular libraries and two full-stack applications. Angular upgrades were always a pain and usually took more than an hour, depending on what went wrong.
With the improved skill, I managed to complete an upgrade in around 30 minutes, including code review and manual testing.
Weβll see how it goes with future Angular versions, but Iβve already successfully used the skill across three different PRs, so Iβd say the results are promising.
"Follow the official Angular Update Guide" is the step I'd want to check. Did Codex actually fetch the guide for 21 β 22, or work from what it remembered? Angular 22 is probably newer than most models' training data.
Next.js 16 approaches this with an
AGENTS.mdrule telling the agent to read the docs bundled innode_modules/next/dist/docs/instead of trusting its memory. On my Next 16 project that matters, sinceparamsandcookies()are async-only now and the old sync code still looks perfectly valid to a model.Good question. That's actually why the skill has a dedicated step for retrieving the official Angular Update Guide. It instructs Codex to use the latest official documentation for each version transition. If the interactive guide isn't accessible, it should fall back to other official Angular sources and migration information. I can't confirm from the PR alone exactly which source Codex retrieved during that particular run, though.
And I agree, relying on model memory for framework upgrades would be pretty risky.
The βimprove the skill from each real failureβ loop is the best part of this post, and the comments already cover clean installs, consumer testing, and regression checklists well. One angle I didnβt see yet is supply chain safety when an agent touches dependencies:
Dependency swaps need a human gate. You mention replacing PrimeNG with Optimus UI. Agents sometimes suggest packages that donβt exist or are lookalikes, so Iβd have the skill list any new or removed packages and wait for approval, instead of installing them on its own.
Review the lockfile diff, not just the build. Changed registry URLs, unexpected new transitive packages, or integrity hash changes are worth a quick look. npm audit and npm audit signatures add a cheap automated check.
Keep publish credentials away from the agent. Since you already use trusted publishing, the agent should never see an npm token. It prepares the branch and PR, and CI with OIDC does the release.
Run installs with --ignore-scripts during validation where possible, so a surprise lifecycle script in a new dependency canβt run on your machine while the agent experiments.
Did the skill ask you before the PrimeNG replacement, or was that a manual decision?
Good points!
The agent actually asked me what I wanted to do: stay on the existing PrimeNG version or upgrade to the paid one. That's when I told it I'd rather switch to Optimus UI. So the replacement was my decision, not something the agent did on its own.
The skill already includes lockfile validation, but I like your suggestion about
npm audit signatures. That's something worth considering for future improvements.Thanks for the detailed feedback.
The npm ci step is the part I would underline. "Works locally" was the agent's definition of done, and CI had a stricter one. Once the clean install became part of the skill, the upgrade had a finish line that matched reality.
I think that is the general lesson for handing upgrades to an agent. The task is small enough to state in one line, Angular N to N+1, but done needs to be written as checks: clean install passes, build passes, tests pass, publish works on the target Node and npm versions. Without that list the agent stops at the first green signal it sees.
Trimming the skill from 1,252 to 701 words while keeping the validation steps is a nice touch too. For the 19 to 22 jump, did you run it as one pass or step through each major version with its own checks?
Agreed. For the 19 β 22 upgrade, I let the agent handle the whole process automatically, without manually stopping to verify each major version.
But thatβs actually a good idea. Adding validation checkpoints after each major version would be safer, especially for bigger version jumps.
Nice practical write-up. Automating the parts of ng update that usually get postponed is a solid use of a skill.
The iterative fixes are the interesting part: catching npm ci lockfile drift before CI, and accounting for the Node/npm versions required by trusted publishing, are the kinds of βworks on my machineβ gaps that pure upgrade scripts often miss. Compressing the skill from ~1,250 words to ~700 while keeping the validation steps is also a good reminder that longer instructions arenβt always better, especially under tighter token budgets.
Useful that it handled a 19 β 22 jump and a PrimeNG β Optimus UI swap in one of the projects. Curious how it behaves on larger apps with more custom schematics or peer-dependency conflicts β those tend to be where the remaining edge cases live.
We are in a situation were it became hard to move on, from Angular 8 to latest version of Angular in the company is a long long trip people doesnt want to endure anymore π«₯
Ouch, Angular 8 to the latest version? That sounds more like an archaeological expedition than an upgrade π€£π€£
I can imagine why nobody wants to touch it, and in that particular scenario, I definitely wouldn't recommend the current version of my skill π
Completely agree. The real value isn't in the AI prompt itself, but in the lessons learned from real-world failures and the validation steps added afterward. Upgrading is the easy part; making sure everything works reliably in production is where the challenge begins. Great example of using AI as an accelerator rather than a replacement for engineering discipline
It illustrates a big pain point for AI agent workflows: local success means nothing. You must simulate clean CIβlike environments to catch dependency and lockβfile issues before code lands on main.
Does the skill stop for approval before a change like replacing PrimeNG? That feels like a product decision, even when it helps the upgrade pass.
The agent actually stopped and asked whether I wanted to stay on the existing PrimeNG version or upgrade to the paid one. That's when I decided to switch to Optimus UI instead.
So it was my decision, not something the agent did automatically. And I agree, that's definitely a product decision.
Thanks, Daniel. That's the pause I was asking about: the agent surfaced the paid upgrade and left the library choice to you.
Have you also tried doing the upgrade in combination with the MCP for the CLI? angular.dev/ai/mcp
Nope, I haven't tried that yet, but thanks for the tip.
The npm ci failure and the later publishing failure look like two separate acceptance checks worth keeping after the skill was shortened. I'd run the clean install and build with the same Node/npm versions as CI, then inspect a packed library in a small consumer project before calling the upgrade done. That checks what a user actually installs without making a real release. It would also make the three-major-version migration a useful regression fixture for future edits to the skill.
sites.google.com/d/1vEkn4k_C1zLubc...
ε¦ε°δΊ
good