Angular 21 (November 2025) and 22 (June 2026) finish the move to “modern Angular”: zoneless apps, OnPush by default, stable Signal Forms and resources, plus new DI APIs (@Service, injectAsync). Below are the important changes, taken from the official changelog, each linked to the page that explains it.
- Change detection
- zoneless by default
- OnPush by default
- Forms
- Signal Forms experimental
- Signal Forms stable
- Async data
- resource / httpResource experimental
- stable + chain + status params
- DI
- —
@Service(),injectAsync()- Template
- regex, spread, arrow functions, instanceof,
@default never - comments in tags,
?.→ undefined,@boundary(22.2) - HTTP
- HttpClient without setup
- Fetch by default
- Testing
- Vitest by default
- getLastFixture, createDirective (22.2)
- UI
- Angular Aria
- Aria mature, WebMCP experimental
All changes, filterable
Filter by version and type. “Breaking” = what to check when you upgrade.
51 changes
22.2
6 changes- new @boundary (developer preview)A block that isolates rendering errors: @boundary { … } @error (let e = $error; let reset = $reset) { … }.
- new TestBed.createDirective()Test directives without a manual host component.
- new Router: RedirectCommand thrown, withAutoCleanupInjectors stableYou can throw RedirectCommand from guards/resolvers; route injectors can be destroyed automatically.
- new Templates can access private membersThe recommendation stays protected for template members.
- new viewChild / contentChild with read: InjectorGet a child’s injector through a query.
- new Signal Forms: permanent hidden fieldsPlus improvements for WebMCP integration.
22.1
3 changes22.0
June 2026 19 changes- breaking OnPush by defaultComponents without changeDetection are OnPush. ng update adds Eager where needed.
- stable Signal Forms — public APIform(), [formField], [formRoot], validators, FormValueControl, validateHttp / validateAsync with debounce, reloadValidation, getError().
- stable resource / rxResource / httpResourceStable. New: ResourceParamsStatus.IDLE/LOADING, ctx.chain(), SSR cache, synchronous values in streams.
- new @Service()New decorator for services auto-provided in root. Only inject() (no constructor DI). Options: autoProvided, factory.
- new injectAsync()Lazily loaded services, with prefetch: onIdle.
- new debounced() (experimental)A debounced version of a signal, like Resource.
- new Comments inside tags<div // comment class="x">.
- new @defer (on idle(500))Timeout for idle and a configurable idle service (provideIdleServiceWith).
- new TestBed.getLastFixture()The last fixture created.
- new WebMCP (experimental)provideExperimentalWebMcpTools / declareExperimentalWebMcpTool — the app exposes tools to AI agents in the browser; signal forms can be exposed automatically.
- breaking Fetch as the default HTTP backendwithFetch() is deprecated. For upload progress: withXhr(). reportProgress → reportUploadProgress / reportDownloadProgress.
- breaking paramsInheritanceStrategy: "always"Child routes inherit params and data from all parents.
- breaking ?. returns undefined in templatesAs in TypeScript. nullishCoalescingNotNullable / optionalChainNotNullable diagnostics may appear.
- breaking TypeScript 6, no Node 20TypeScript < 6 is no longer supported.
- breaking Removed: ComponentFactoryResolver, ComponentFactory, createNgModuleRef, provideRoutes, Hammer.jsUse the class directly in createComponent, createNgModule, provideRouter.
- breaking Stricter compilerError for inputs/outputs bound twice, multiple matching selectors, data-* attributes no longer bind inputs.
- breaking min/max in Signal Forms are numeric onlyThey no longer accept strings.
- breaking CanMatchFn: currentSnapshot is requiredClass implementations of CanMatch must accept a third argument.
- new Incremental hydration by defaultwithIncrementalHydration() is no longer needed for SSR.
21.2
6 changes- new Arrow functions and instanceof in templatesitems().filter(i => i.ok), err instanceof HttpErrorResponse.
- new @default never; — exhaustive switchA forgotten case in a union becomes a compile error.
- new ChangeDetectionStrategy.EagerAlias for Default, preparing for OnPush by default in v22.
- new Resource snapshotsresource.snapshot() and resourceFromSnapshots() for composing resources.
- new Signal Forms: FormRoot, parse errors, SignalFormControlThe [formRoot] directive, parse errors for native inputs, compatibility with Reactive Forms.
- new ngTemplateOutlet with an “outlet” injector[ngTemplateOutletInjector]="'outlet'".
21.1
4 changes- new @switch with multiple cases@case (a) @case (b) { … } — the same block for several values.
- new Spread in templates[...a, ...b], { ...obj }, fn(...args).
- new Focus on a Signal Forms fieldfield().focus() focuses the bound control.
- new Router: scroll, cleanup, isActive as a signalScroll controls on navigation, an isActive() function that returns a signal, wildcards with segments.
21.0
November 2025 13 changes- new Zoneless by defaultNew apps no longer include zone.js. Change detection is triggered by signals, events and markForCheck.
- new Signal Forms (experimental)form(), [field] / [formField], schema-based validation, debounce(). Becomes public API in v22.
- new Vitest as the default runnerng test uses Vitest through @angular/build:unit-test. Karma is deprecated.
- new Angular AriaHeadless, accessible directives: Accordion, Combobox, Grid, Listbox, Menu, Tabs, Toolbar, Tree.
- new HttpClient without setupHTTP services are provided in root; provideHttpClient() is only for configuration.
- new Regex in templatesYou can write /^\d+$/.test(x) directly in expressions.
- new Generic SimpleChangesngOnChanges(changes: SimpleChanges<MyCmp>) — typed keys.
- new IntersectionObserver options in @defer@defer (on viewport({ rootMargin: "200px" })).
- new Migrations ngClass → class, ngStyle → styleng g @angular/core:ngclass-to-class and ngstyle-to-style.
- breaking Type-checking for host bindings is on by defaultHidden type errors in host: {} can appear at build time. It can be temporarily disabled with typeCheckHostBindings: false.
- breaking TypeScript ≥ 5.9Older TypeScript versions are no longer supported.
- breaking lastSuccessfulNavigation is a signalrouter.lastSuccessfulNavigation() must be called.
- breaking Removed: moduleId, custom interpolation, NgModuleFactoryOld metadata options removed from the API.
How to upgrade
# Upgrade step by step (don't skip major versions)
ng update @angular/core@21 @angular/cli@21
ng update @angular/core@22 @angular/cli@22
# Interactive guide with every step for your combination of versions:
# https://angular.dev/update-guide
# What ng update does automatically for v22:
# - adds ChangeDetectionStrategy.Eager where changeDetection was not set
# - keeps HttpXhrBackend where it is needed (withXhr)
# - adds currentSnapshot to CanMatch
# - temporarily disables the new diagnostics for ?. and ??
# - enables strictTemplates in tsconfigRecommended order after the upgrade
- Build and tests green, with
Eageradded automatically. - Move state to signals, feature by feature (signals, resource).
- Remove
Eagerfrom migrated components and check (change detection). - Write new forms directly in Signal Forms; old ones stay on Reactive until you have a reason to move them.