Jul 15, 2026

Angular 21 to 22: Breaking Changes and How to Fix Them

Angular22UpgradeOnPushSignalFormsMigration

OnPush is the new default, route params inherit everywhere, and Node 22 is mandatory. Step-by-step guide to upgrade Angular 21 to 22 without surprises.

Angular 21 removed the old guard — Karma out, zone.js optional. Angular 22 goes further: it changes what a default component is.

For the first time, OnPush is the default change detection strategy, route parameters flow down the whole tree, and the framework doubles down on being agent-friendly infrastructure. Here is what breaks, and how to fix it.

TL;DR — upgrade Angular 21 to 22 in 4 steps:

node --version # must be 22+ (Node 20 is no longer supported) npm install -g @angular/cli@latest ng update @angular/core@22 @angular/cli@22 ng test

The three changes most likely to hit you: OnPush is the new default change detection (a migration adds ChangeDetectionStrategy.Eager to your existing components), route params now inherit with 'always' instead of 'emptyOnly', and Node 22 + TypeScript 6.0 are the new minimums. Details and fixes below.

The “Stop Everything” Breaking Changes

Breaking changeWhat breaksFix
OnPush is the new default change detectionNothing, if the automatic migration runs — it stamps ChangeDetectionStrategy.Eager on existing componentsLet the migration add Eager; embrace signals in new code
Route params inherit with 'always'Child routes now see every parent param/data, colliding param names may resolve unexpectedlyRename colliding params, or set paramsInheritanceStrategy: 'emptyOnly' to opt out
Node 22 + TypeScript 6.0 are mandatoryBuild fails immediately on Node 20 or TypeScript 5.9Upgrade Node and TypeScript before running ng update
Smaller sharp edgesDuplicate input bindings now a compile error; data-* attributes bind as attributes; transfer cache skips credentialed requestsAudit templates and SSR caching assumptions

1. OnPush Is the Default Now

This is the philosophical headline of v22. A component that doesn’t set changeDetection used to mean “check me on every cycle.” In Angular 22 it means ChangeDetectionStrategy.OnPush.

What breaks: Nothing in your existing code — if you let the migration do its job. ng update adds the new ChangeDetectionStrategy.Eager value (the old check-always behavior, now with a name) to every component that relied on the old default.

What actually changes: Every new component you generate is OnPush. If your team’s habits still assume mutation-based updates (“I changed the property, why didn’t the view update?”), v22 is where those habits die.

The Fix:

  • Let the automatic migration stamp Eager on legacy components. Don’t fight it during the upgrade.
  • For new code, embrace signals — signal(), computed(), and input() make OnPush invisible because updates are tracked at the value level.
  • Migrate old components off Eager incrementally. The Angular MCP server’s onpush_zoneless_migration tool analyzes a component’s dependency graph before you flip the strategy — I covered it in the Angular MCP guide.

2. Route Params Inherit Everywhere

The router’s paramsInheritanceStrategy default changed from 'emptyOnly' to 'always'.

What breaks: Child routes now see every parent route’s params and data. If a child route reads a param name that also exists on a parent (:id on both a parent and child, for example), it may now resolve to a value it never saw before. Components with defensive “param is undefined” branches may silently take the other branch.

The Fix: Audit components that read route params or data. If you need the old behavior back, it’s one line:

provideRouter(routes, withRouterConfig({ paramsInheritanceStrategy: 'emptyOnly', }))

Prefer renaming colliding params (:userId vs :orderId) over reverting globally — the 'always' default is genuinely better for deep-linked detail pages.

3. Node 22 and TypeScript 6.0 Are Mandatory

What breaks: The build, immediately, if your CI or local environment runs Node 20 (now past end-of-life) or TypeScript 5.9.

The Fix: Upgrade Node to 22, 24, or 26 and TypeScript to 6.0+ before running ng update. Check your CI images, your Dockerfiles, and your engines field — the local upgrade is always the easy half.

4. Smaller Sharp Edges

  • Duplicate input bindings are a compile error. Binding the same input twice on one element used to be silently tolerated; now the template compiler rejects it.
  • data-* attributes are no longer treated as property bindings — they bind as attributes, which is what you almost certainly wanted anyway.
  • The HTTP transfer cache skips credentialed requests by default (cookie-bearing and withCredentials), so authenticated responses can’t leak across SSR sessions. If you relied on caching those, you now have to opt in deliberately.

The New Toys: Features You’ll Actually Use

Signal Forms Are Stable

The experimental warnings are gone. The form()/field() model from v21 is now the blessed, typed, signal-first way to build forms. If you held off adopting them in 21, v22 is the green light.

resource() and httpResource Are Production-Ready

Async data as a signal, with loading and error states built in. Together with stable Signal Forms and OnPush-by-default, the signal-first architecture is no longer “the direction Angular is heading” — it’s just how Angular works.

Selectorless Components

Import a component and use it in the template directly — no string selector indirection, better type safety, easier refactoring.

The Agentic Story Continues

v22 extends the MCP + Skills stack introduced around v21: the CLI’s MCP server plus the skills layer that teaches agents to write signal-first, OnPush-correct code. I’ve written about this in depth: agent-safe component patterns and exhaustive types for hallucination-free agents.

Summary: The Checklist

  1. Node 22+, TypeScript 6.0+ — environment first.
  2. ng update @angular/core@22 @angular/cli@22 and let the Eager migration run.
  3. Audit route param reads (or pin 'emptyOnly' back).
  4. Run the test suite; fix duplicate input bindings the compiler now flags.
  5. Adopt Signal Forms and resource() in new code; peel components off Eager over time.

The official interactive checklist lives at angular.dev/update-guide, and the release announcement at angular.dev/events/v22.


Coming from an older version? Start with Angular 20 to 21: Breaking Changes and How to Fix Them, or see every migration path in the Angular Upgrade Guide.

Written by

Antonio Cárdenas

Google Developer Expert in Angular · Verified GDE profile · Google Developers profile

My technical writing reaches 100,000+ developers in English and Spanish. I've migrated production Angular apps from v8 to v22 — everything I publish is built from real project work, not documentation re-reads.

Frequently asked questions

FAQs

When was Angular 22 released?

Angular 22 was released in June 2026, announced around Google I/O. It is a major release that makes ChangeDetectionStrategy.OnPush the default for components, changes route parameter inheritance to 'always', stabilizes Signal Forms and the Resource APIs, and requires Node.js 22+ and TypeScript 6.0+.

What are the main breaking changes in Angular 22?

The three major breaking changes are: (1) components without an explicit changeDetection now default to OnPush instead of check-always — a new ChangeDetectionStrategy.Eager value represents the old behavior; (2) the router's paramsInheritanceStrategy default changed from 'emptyOnly' to 'always', so child routes now inherit all parent params and data; (3) Node.js 20 and TypeScript 5.9 are no longer supported — the minimums are Node 22 and TypeScript 6.0.

How do I upgrade from Angular 21 to Angular 22?

First make sure you are on Node.js 22+ and TypeScript 6.0+. Then run ng update @angular/core@22 @angular/cli@22. The automatic migration adds ChangeDetectionStrategy.Eager to your existing components so their change detection behavior does not change. After updating, audit route param reads and run your test suite.

Is OnPush mandatory in Angular 22?

No. OnPush is only the new default for components that do not set changeDetection explicitly. The old check-always behavior still exists under the new name ChangeDetectionStrategy.Eager, and the ng update migration adds Eager to your existing components automatically so nothing breaks. New components you generate will use OnPush unless you opt out.

Are Signal Forms stable in Angular 22?

Yes. Signal Forms shipped as experimental in Angular 21 and became stable in Angular 22, with the experimental warnings removed. The resource() and httpResource APIs are also production-ready in v22, completing the signal-first data story alongside zoneless change detection.

Keep reading

Building something with Angular?

I write about Angular architecture, Signals and the tooling around them — migration guides, real upgrade paths, and the catches most posts skip.

Browse all articlesAbout me

More from the blog