Angular 15 to Angular 16 Upgrade
Upgrade an Angular application from Angular 15.x to Angular 16.x using a controlled major-hop process. Use when the project is ready to move from Angular 15 to Angular 16 and needs explicit handling f
SKILL.mdskills/angular/upgrades/hops/angular-15-to-16/SKILL.md
GitHubAngular 15 to Angular 16 Upgrade
Purpose
Upgrade an Angular application from Angular 15.x to Angular 16.x using a controlled major-hop process.
This hop is a hard compatibility boundary because Angular 16 removes ngcc. Projects on Angular 16 and later no longer support View Engine libraries.
When to Use
- The project uses Angular 15.x.
- The target next hop is Angular 16.x.
- The Angular 14 -> 15 validation gate passed.
- Angular Material status is known.
- View Engine / ngcc library status is known or ready to be audited.
- SSR usage is known.
- TransferState usage is known.
- Dynamic component creation usage is known.
When Not to Use
- The project is AngularJS 1.x.
- The project is Angular 14.x or lower.
- The project is already Angular 16 or later.
- The previous Angular 14 -> 15 validation gate failed.
- Critical View Engine libraries exist and no Angular 16-compatible version is available.
- The task is only standalone migration.
- The task is only signals adoption.
Mandatory Cross-Skill Routing
Before upgrading to Angular 16, run:
skills/angular/upgrades/libraries/angular-ngcc-view-engine-removal-v16/SKILL.md
Use it to detect:
ngccscripts- View Engine-only libraries
__ivy_ngcc__metadata.json- postinstall compatibility scripts
If a critical View Engine-only library is detected, return FAIL_BLOCK_NEXT_HOP.
Required Inputs
package.json- lock file
- Angular package versions
- Angular CLI version
- Angular Material version
- Angular CDK version
- TypeScript version
- RxJS version
zone.jsversion- Node.js version
angular.jsontsconfig.jsontsconfig.app.jsontsconfig.spec.json- Angular libraries
- library build scripts
postinstallscriptsngccreferences__ivy_ngcc__references- Angular Universal usage
- SSR entry points
renderModuleFactoryrenderModulerenderApplicationTransferStateComponentFactoryResolverViewContainerRef.createComponentEnvironmentInjector.runInContextReflectiveInjectorInjector.createentryComponentsANALYZE_FOR_ENTRY_COMPONENTSmoduleId- Router events
RendererType2.stylesQueryList.filterBrowserModule.withServerTransitionAPP_ID- current build/test/lint/e2e scripts
- production build scripts
- SSR/prerender scripts
- screenshot/golden tests
Dependency Upgrade
Node.js
Angular 16 supports Node.js v16 and v18.
Block the upgrade when Node.js is not supported.
TypeScript
Angular 16 supports TypeScript 4.9.3 or later.
Zone.js
Angular 16 supports Zone.js 0.13.x or later.
Angular Core and CLI
Run:
ng update @angular/core@16 @angular/cli@16
If the local CLI is unreliable, use:
npx @angular/cli@16 update @angular/core@16 @angular/cli@16
Angular Material
If the project uses Angular Material, update to v16 after Angular core and CLI succeed.
ng update @angular/material@16
or:
npx @angular/cli@16 update @angular/material@16
Do not upgrade Material beyond v16 in this hop.
Required Code Changes
ngcc and View Engine removal
Remove ngcc scripts only after confirming all Angular libraries are Ivy-compatible.
Gate behavior:
- Critical View Engine-only dependency =
FAIL_BLOCK_NEXT_HOP - Unknown Angular library compatibility =
FAIL_BLOCK_NEXT_HOP ngccscript still required =FAIL_BLOCK_NEXT_HOP
Router event typing
Review code that handles router events and update assumptions around RouterEvent and NavigationSkipped.
RendererType2.styles
Flatten nested style arrays to a flat string array where required.
BrowserPlatformLocation tests
Review router and location tests that rely on mocked platform location behavior.
ApplicationConfig import
Import ApplicationConfig from @angular/core.
renderModuleFactory removal
Replace renderModuleFactory with renderModule.
XhrFactory import
Import XhrFactory from @angular/common.
BrowserModule.withServerTransition
Replace with APP_ID where multiple apps require unique app IDs.
EnvironmentInjector.runInContext
Replace with runInInjectionContext where applicable.
Dynamic component creation
Use ViewContainerRef.createComponent without factory resolver where possible.
renderApplication
Update renderApplication usage to the Angular 16 signature.
PlatformConfig
Remove deprecated server platform config usage.
moduleId
Remove moduleId from @Component and @Directive.
TransferState
Import TransferState, makeStateKey, and StateKey from @angular/core.
entryComponents and ANALYZE_FOR_ENTRY_COMPONENTS
Remove both from active metadata.
ngTemplateOutletContext
Review stricter typing for template outlet context objects.
APF / ES2022
Review custom build tooling for ES2022-compatible distributed output.
EventManager
Remove EventManager.addGlobalEventListener usage.
BrowserTransferStateModule
Remove BrowserTransferStateModule.
ReflectiveInjector
Replace with Injector.create.
QueryList.filter
Review type-guard narrowing behavior.
Do
- Run the ngcc and View Engine audit before changing Angular package versions.
- Review SSR, TransferState, and dynamic component creation together when they are used in the project.
- Validate Angular Material/MDC, router, and build tooling after the update.
- Keep library compatibility and build output as explicit gate conditions.
Do Not
- Do not keep
ngccas a workaround. - Do not continue if critical View Engine-only libraries remain.
- Do not ignore ES2022 build-tool compatibility.
- Do not mix standalone or signals adoption into this hop.
Review Checklist
- Node.js, TypeScript, and Zone.js are compatible.
-
ngccis not required. - View Engine-only libraries are resolved or blocked.
- SSR and TransferState paths are updated where used.
- Dynamic component creation no longer relies on factory resolvers.
-
entryComponentsandANALYZE_FOR_ENTRY_COMPONENTSare removed. - Material/MDC and style regressions are reviewed.
- Production build passes.
Validation
Run only existing commands:
npm run buildnpm run testnpm run lintnpm run e2eng build --configuration productionnpm run build:ssrnpm run serve:ssrnpm run prerender
Validation Gate
Use FAIL_BLOCK_NEXT_HOP when:
- Node.js is unsupported
- TypeScript is unsupported
- Zone.js is unsupported
- build fails
- tests fail
- production build fails
- Angular CLI update is incomplete
- Angular Material update is incomplete in a Material project
- ngcc is still required
- View Engine-only critical libraries remain
- Angular library compatibility is unknown
- SSR still uses removed APIs
TransferStateimports are unresolvedBrowserTransferStateModuleremainsComponentFactoryResolvermigration is unresolvedReflectiveInjectorremainsANALYZE_FOR_ENTRY_COMPONENTSremainsentryComponentsremains in active metadatangTemplateOutletContexttyping errors remain- custom build tooling cannot consume ES2022 output
EventManager.addGlobalEventListenerremains- dynamic component loaders fail
- multiple apps have non-unique
APP_IDs - Material/MDC/style regressions are unreviewed
Expected Output
- Upgrade summary.
- ngcc/View Engine audit summary.
- SSR and DI migration summary.
- Validation result.
- Gate decision.
Exit Criteria
- Angular 16 upgrade is complete.
ngccis not required.- View Engine compatibility is explicit.
- Validation gate is explicit.
- The next hop is not started automatically.