loiane/spring-ai-angular/angular-v21-migrate
Claude Code and agent skill by loiane/spring-ai-angular
- community
Checking that the SKILL.md file is still in the repository.
Migrate Angular projects to v21+: remove zone.js, remove Jasmine/Karma, migrate tests to Vitest, enable zoneless change detection. Use when: upgrading Angular, removing zone.js, replacing Karma with Vitest, converting Jasmine tests to Vitest, Angular v21 migration, zoneless Angular.
Install
npx vskill@latest install loiane/spring-ai-angular/angular-v21-migrateSKILL.md
Angular v21 Migration — Remove zone.js, Jasmine/Karma → Vitest
Automates the key breaking changes and modernization steps when upgrading an Angular project to v21+.
When to Use
- Upgrading an Angular project to v21 or later
- Removing zone.js from an existing Angular app
- Replacing Jasmine/Karma test runner with Vitest
- Converting Jasmine test syntax to Vitest
- Auditing a project for migration readiness
Scope
This skill handles three independent migration tracks that can be run individually or together:
- Remove zone.js — switch to
provideZonelessChangeDetection() - Remove Jasmine/Karma — uninstall packages, remove config files, clean angular.json
- Migrate to Vitest — install Vitest, configure it for Angular, convert test files
Prerequisites
- Angular CLI v21+ installed (
ng version) - Project already updated to Angular v21 packages (
ng update) - All existing tests pass before migration (run them first)
Procedure
Phase 0 — Audit
Before making changes, audit the project to understand what needs migration.
- Run the audit script or perform these checks manually:
- Check
package.jsonforzone.js,karma,jasmine-core,@types/jasmine,karma-*packages - Check
angular.jsonfor@angular/build:karmatest builder - Check
tsconfig.spec.jsonfor"types": ["jasmine"] - Check
src/main.tsandsrc/polyfills.tsforimport 'zone.js' - Check
app.config.tsforprovideZoneChangeDetection()vsprovideZonelessChangeDetection() - Count
.spec.tsfiles to estimate test migration effort - Check for
karma.conf.jsorkarma.conf.tsat project root
- Report findings before proceeding
Phase 1 — Remove zone.js
Follow the zone.js removal checklist:
- Switch to zoneless change detection in
app.config.ts:
- Replace
provideZoneChangeDetection({ eventCoalescing: true })withprovideZonelessChangeDetection() - Import
provideZonelessChangeDetectionfrom@angular/core - Remove the
provideZoneChangeDetectionimport if no longer used
- Remove zone.js from polyfills in
angular.json:
- In
architect.build.options, remove"zone.js"from thepolyfillsarray - In
architect.test.options, remove"zone.js"and"zone.js/testing"from thepolyfillsarray
- Remove zone.js import from
src/main.tsorsrc/polyfills.tsif present - Uninstall zone.js:
``bash npm uninstall zone.js ``
- Update all test files — add
provideZonelessChangeDetection()toTestBed.configureTestingModuleproviders if not already present - Verify — build and run tests to confirm nothing breaks
Phase 2 — Remove Jasmine/Karma
Follow the Karma removal checklist:
- Delete config files:
karma.conf.jsorkarma.conf.ts(if they exist)
- Replace the Karma test architect target in
angular.json:
- Remove
@angular/build:karma - Add
"test": { "builder": "@angular/build:unit-test" }
- Clean `tsconfig.spec.json`:
- Remove
"jasmine"fromcompilerOptions.types - Keep the file for Angular unit-test builder and update it in Phase 3
- Uninstall Jasmine/Karma packages:
``bash npm uninstall karma karma-chrome-launcher karma-coverage karma-jasmine karma-jasmine-html-reporter jasmine-core @types/jasmine ``
- Remove test scripts from
package.jsonthat referenceng testorkarma
Phase 3 — Migrate to Vitest
Follow the Vitest migration guide:
- Install Vitest dependencies:
``bash npm install -D vitest jsdom ``
- Use Angular's built-in unit test builder (no
vitest.config.tsrequired):
- In
angular.json, set:
``json { "test": { "builder": "@angular/build:unit-test" } } ``
- Update `tsconfig.spec.json` to Angular v21 pattern:
- Set types to include vitest globals:
``json { "extends": "./tsconfig.json", "compilerOptions": { "outDir": "./out-tsc/spec", "types": ["vitest/globals"] }, "include": ["src/**/*.d.ts", "src/**/*.spec.ts"] } ``
- Update `package.json` scripts:
``json { "test": "ng test", "test:ci": "ng test --watch=false --progress=false" } ``
- Convert test files — apply syntax transformations from the Jasmine-to-Vitest cheatsheet:
- Replace
jasmine.Spy→vi.SpyInstance(or useMockInstancetype) - Replace
spyOn(obj, 'method')→vi.spyOn(obj, 'method') - Replace
jasmine.createSpy('name')→vi.fn() - Replace
jasmine.createSpyObj('name', ['m1', 'm2'])→ manual mock object withvi.fn() - Replace
.and.returnValue(x)→.mockReturnValue(x) - Replace
.and.callFake(fn)→.mockImplementation(fn) - Replace
.and.callThrough()→ (default behavior in Vitest, remove the call) - Replace
.toHaveBeenCalledTimes(n)→ same (compatible) - Replace
.toHaveBeenCalledWith(...)→ same (compatible) - Replace
fail('msg')→expect.unreachable('msg')orthrow new Error('msg') - Replace
donecallbacks withasync/awaitor fake timers (vi.useFakeTimers) to avoidTestContextcallback typing issues describe,it,expect,beforeEach,afterEach— same API, no changes needed- Keep
TestBedimports as-is
- Run tests:
``bash npm test ``
Phase 4 — Final Verification
npm run build— production build must succeednpm test— all tests pass with Vitestnpm run e2e— end-to-end tests still pass (if applicable)- Verify no references to
zone.js,karma, orjasmineremain in source files:
``bash grep -r "zone.js\|karma\|jasmine" --include="*.ts" --include="*.json" --include="*.js" src/ *.json *.js 2>/dev/null ``
- Review
package.json— no leftover Karma/Jasmine/zone.js dependencies
Common Gotchas
- `fixture.detectChanges()` in zoneless mode: Still works but change detection is triggered by signals. Manual
detectChanges()may still be needed in tests. - `fakeAsync` / `async`: These utilities from
@angular/core/testingstill work withprovideZonelessChangeDetection()in tests. - Third-party libraries depending on zone.js: Check if any imported libraries rely on Zone.js patching (e.g., some older Material components). Angular Material v21+ is fully zoneless-compatible.
- `HttpClientTestingModule` is deprecated: Use
provideHttpClient()+provideHttpClientTesting()withHttpTestingControllerinstead. - Test files with `jasmine.clock()`: Replace with
vi.useFakeTimers()/vi.useRealTimers(). - `done` callback parameter errors (`TestContext` has no call signatures): Replace callback-style tests with
async/await(firstValueFrom) or fake timers.
Security
- Security scanPassed, 100 of 100Pattern checks on the skill's files.
- Model reviewNot runA model review is scheduled for the next rescan.
Quality evaluation
- Task evaluationNot runNo evaluation yet. Run one in Skill Studio.
Source
- SKILL.md in the repositoryCheckingangular-ai/.github/skills/angular-v21-migrate/SKILL.md
Popularity
- Repository stars
- 52
- Repository forks
- 13
- 7-day trend score
- 20
Stars and forks are for the whole GitHub repository, not this skill alone. Not refreshed yet.
Works with
Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.
- Claude Code
- Cursor
- GitHub Copilot
- Windsurf
- Codex
- Gemini CLI
- Cline
- Amp
- Roo Code
- Goose
- Continue
- Kilo Code
- Junie
- Trae
- OpenHands
- Qwen Code
- AI Agent
- Tabnine Chat
- Sourcegraph Cody
- Amazon Q
- Firebase Genkit
- Sweep
- Devin
- Phind
- Mentat
- Claude Desktop
- Aider
- GPT Pilot
- Plandex
- bolt.new
- v0
- Replit Agent
- Anse
- TypingMind
- BetterChatGPT
- LibreChat
- Warp AI
- Pieces
- Fig AI
Embed badge
[](https://verified-skill.com/skills/loiane/spring-ai-angular/angular-v21-migrate)