Angular 20 to Angular 21 Upgrade

Upgrade an Angular application from Angular 20.x to Angular 21.x using a controlled major-hop process. Use when the project is ready to move from Angular 20 to Angular 21 and needs explicit handling f

SKILL.md

GitHub

Angular 20 to Angular 21 Upgrade

Purpose

Upgrade an Angular application from Angular 20.x to Angular 21.x using a controlled major-hop process.

When to Use

  • The project uses Angular 20.x.
  • The target next hop is Angular 21.x.
  • The Angular 19 -> 20 validation gate passed.
  • Angular Material usage is known.
  • SSR usage is known.
  • AngularJS hybrid usage is known.
  • Host binding usage is known.
  • Test strategy is known.

When Not to Use

  • The project is AngularJS 1.x.
  • The project is Angular 19.x or lower.
  • The project is already Angular 21 or later.
  • The previous Angular 19 -> 20 validation gate failed.
  • Angular Material v20 migration has unresolved critical blockers.
  • SSR security posture is unknown in an SSR app.
  • AngularJS hybrid migration still uses removed APIs without a plan.
  • The task is only zoneless migration.

Mandatory Cross-Skill Routing

Before upgrading from Angular 20 to Angular 21, run:

skills/angular/upgrades/changelog/angular-major-changelog-risk-review/SKILL.md

If the changelog review returns FAIL_BLOCK_NEXT_HOP, do not continue to Angular 21.

Recommended Cross-Skill Routing

  • skills/angular/upgrades/zone/angular-v21-zone-change-detection-root-provider/SKILL.md
  • skills/angular/upgrades/ssr/angular-ssr-allowed-hosts-v21-security/SKILL.md
  • skills/angular/upgrades/testing/angular-v21-router-zone-platformlocation-tests/SKILL.md
  • skills/angular/upgrades/templates/angular-v21-host-binding-typecheck/SKILL.md
  • skills/angular/upgrades/components/angular-v21-custom-elements-signal-inputs/SKILL.md
  • skills/angular/upgrades/hybrid/angular-v21-upgrade-adapter-removal/SKILL.md
  • skills/angular/upgrades/forms/angular-v21-formarray-directive-conflict/SKILL.md
  • skills/angular/upgrades/modules/angular-v21-ngmodulefactory-removal/SKILL.md

Required Inputs

  • package.json
  • lock file
  • Angular package versions
  • Angular CLI version
  • Angular Material version
  • Angular CDK version
  • TypeScript version
  • RxJS version
  • Zone.js version
  • Node.js version
  • angular.json
  • tsconfig.json
  • tsconfig.base.json
  • tsconfig.app.json
  • tsconfig.spec.json
  • emitDeclarationOnly
  • typeCheckHostBindings
  • provideZoneChangeDetection
  • ignoreChangesOutsideZone
  • moduleId
  • ApplicationConfig
  • ngComponentOutletContent
  • createCustomElement
  • customElements.define
  • signal inputs
  • UpgradeAdapter
  • @angular/upgrade
  • @angular/upgrade/static
  • FormArray
  • formArray
  • NgModuleFactory
  • dynamic module loading
  • Router.lastSuccessfulNavigation
  • router navigation tests
  • PlatformLocation tests
  • SSR files
  • SSR engines
  • allowedHosts
  • trustProxyHeaders
  • host headers
  • current build/test/lint/e2e scripts
  • production build scripts
  • SSR/prerender scripts
  • screenshot/golden tests

Dependency Upgrade

Node.js

Use the Angular compatibility matrix as the source of truth.

TypeScript

Angular 21 requires TypeScript 5.9 or later.

Angular Core and CLI

Prefer updating to the latest Angular 21 patch:

ng update @angular/core@^21 @angular/cli@^21

If local CLI is unreliable, use:

npx @angular/cli@21 update @angular/core@^21 @angular/cli@^21

Angular Material

If the project uses Angular Material, update to v21 after Angular core and CLI succeed.

ng update @angular/material@^21

or:

npx @angular/cli@21 update @angular/material@^21

Required Code Changes

1. Signal inputs with custom elements

Review Angular custom elements using signal inputs and ensure direct property access where required.

2. Zone-based apps must provide provideZoneChangeDetection

Provide zone change detection at the application root when the app remains Zone-based.

3. Remove ignoreChangesOutsideZone

Remove ignoreChangesOutsideZone from zone configuration.

4. Remove custom interpolation markers

Keep only default interpolation markers.

5. Remove moduleId

Remove moduleId from components and directives.

6. Strict ngComponentOutletContent typing

Use Node[][] | undefined.

7. Host binding type checking

Fix host binding errors or temporarily bridge them with explicit follow-up.

8. ApplicationConfig import migration

Import ApplicationConfig from @angular/core.

9. UpgradeAdapter removal

Remove UpgradeAdapter and use static upgrade APIs.

10. Standalone formArray directive conflict

Rename custom directives or inputs that conflict with Angular forms names.

11. Remove NgModuleFactory

Remove dynamic module loading code that still depends on NgModuleFactory.

12. Remove emitDeclarationOnly

Do not use emitDeclarationOnly in Angular compilation paths.

13. Router lastSuccessfulNavigation is now a signal

Update reads to call it as a signal.

14. SSR CommonEngine allowed hosts

Configure explicit allowedHosts and validate trusted proxy headers.

Do

  • Run the Angular 20 changelog review before changing package versions.
  • Keep SSR security, host binding checks, router, forms, and hybrid APIs explicit.
  • Validate production and SSR builds when they are used.
  • Route risky SSR, router, test, and DI behavior to the dedicated skills.
  • Keep Material/MDC validation explicit if Material is used.

Do Not

  • Do not continue if Angular 20 changelog review failed.
  • Do not keep UpgradeAdapter, NgModuleFactory, moduleId, or ignoreChangesOutsideZone.
  • Do not use allowedHosts: ['*'] without infrastructure validation.
  • Do not mix this hop with zoneless modernization, control flow, defer, or standalone adoption.

Review Checklist

  • Angular 20 changelog review passed.
  • TypeScript 5.9+ is compatible.
  • SSR allowedHosts is explicit.
  • provideZoneChangeDetection is configured when needed.
  • ignoreChangesOutsideZone is removed.
  • Host binding type errors are resolved.
  • UpgradeAdapter is removed.
  • NgModuleFactory is removed.
  • Router.lastSuccessfulNavigation is read correctly.
  • Material/MDC regression risk is reviewed.
  • Production build passes.

Validation

Run only existing scripts:

  • npm run build
  • npm run test
  • npm run lint
  • npm run e2e
  • ng build --configuration production
  • npm run build:ssr
  • npm run prerender
  • npm run serve:ssr

Validation Gate

Use FAIL_BLOCK_NEXT_HOP when:

  • Angular 20 changelog risk review failed
  • Node.js version is unsupported
  • TypeScript version is unsupported
  • build fails
  • tests fail
  • production build fails
  • Angular CLI update is incomplete
  • Angular Material update is incomplete in a Material project
  • provideZoneChangeDetection is missing when needed
  • ignoreChangesOutsideZone remains
  • custom interpolation remains
  • moduleId remains
  • ApplicationConfig is still imported from @angular/platform-browser
  • ngComponentOutletContent typing is unresolved
  • host binding type errors remain
  • UpgradeAdapter remains
  • NgModuleFactory remains
  • emitDeclarationOnly remains in Angular compilation path
  • Router.lastSuccessfulNavigation is accessed as a property
  • custom formArray directive/input conflicts remain
  • router timing tests are unresolved
  • PlatformLocation test failures are unresolved
  • SSR production lacks explicit allowedHosts
  • SSR uses trusted proxy headers without infrastructure validation
  • Material/style regressions are unreviewed
  • workspace config is unstable

Expected Output

  1. Upgrade summary.
  2. Changelog baseline summary.
  3. SSR, router, DI, and legacy API migration summary.
  4. Validation result.
  5. Gate decision.

Exit Criteria

  • Angular 20 changelog review has passed.
  • Angular dependencies are upgraded to Angular 21-compatible versions.
  • Angular CLI is upgraded to v21.
  • Angular Material/CDK are upgraded to v21 only if used.
  • Node.js compatibility is confirmed.
  • TypeScript 5.9+ compatibility is confirmed.
  • SSR allowedHosts is explicit where used.
  • Legacy APIs are removed.
  • Router, forms, and host binding changes are reviewed.
  • Production build has been validated.
  • Validation gate result is explicit.
  • The next hop is not started automatically.