<link rel="stylesheet" href="/assets/fonts/jetbrains-mono/jetbrains-mono.css" />
All posts

What's new in Angular 22: Stable signal forms, Resource API and Angular Aria

Angular 22, released on 3 June 2026, is the latest stable version of the framework at the time of this writing. Compared to Angular 21 (November 2025, which had made zoneless the default and introduced Signal Forms as an experimental API), this release consolidates into stable production-ready everything that was still in developer preview: Signal Forms, Resource API and Angular Aria become officially usable in production, the defaults of some APIs change towards more modern patterns, and a first layer of AI tooling integrated into the CLI arrives.

As always with a recent release, check the exact version installed and the release notes official before planning an upgrade in production: ng version and npm view @angular/core versions return the real state of your project and npm registry, more reliable than any static summary.

Quick Overview

  • Stable Signal Forms: The Signal-based forms system, experimental in v21, is now production-ready.
  • Resource API stable: resource(), rxResource(), and httpResource() go from experimental to stable.
  • Angular Aria stable: Package @angular/aria for accessibility pattern moves from developer preview to general availability.
  • OnPush as default: new components use OnPush instead of Eager for change detection.
  • Fetch API as default for HttpClient: replaces
  • AI tooling in the CLI: Angular Skills and experimental WebMCP support for coding agents.
  • TypeScript 6 required: Minimum requirement raised, Node 20 no longer supported (Node 22 minimum).

Detail Feature

Signal Forms: from Experimental to Stable

Signal Forms combines the strong typing of traditional reactive forms with granular responsiveness of Signal, eliminating much of the boilerplate of FormGroup/FormControl. In this version validators minDate()/maxDate() arrive, native debounce on blur events, and a getError() method to recover targeted errors without traverse the entire form tree.

// Signal Forms — validazione con debounce sul blur, stabile da v22
const form = signalForm({
  email: field('', { validators: [required(), email()] }),
});
debounce(form.email, 'blur', 300);

Resource API: Reactive Data Fetching

// httpResource() — fetching dichiarativo, nessun switchMap manuale
userResource = httpResource(() => `/api/users/${this.userId()}`);
// userResource.value(), userResource.isLoading(), userResource.error() sono Signal reattivi

New in this version: a chain() method to compose mutually dependent resources on the other without manually nesting effect(), and SSR side cache support via an id option, useful for avoiding double fetching between rendering server and hydration client.

OnPush by Default and Fetch API by Default

// Da Angular 22, un componente senza changeDetection esplicito è OnPush per default
@Component({ selector: 'app-widget', template: `...` })
export class WidgetComponent {} // equivalente a changeDetection: ChangeDetectionStrategy.OnPush

HttpClient uses Fetch API instead of XMLHttpRequest without needing withFetch() explicit (now deprecated for removal); be careful if your code depends on reportProgress for upload, because progress reporting in upload is not supported by the Fetch implementation and must be handled with the new ones reportUploadProgress/reportDownloadProgress.

@Service Decorator and injectAsync()

// @Service — scorciatoia per @Injectable({ providedIn: 'root' }), richiede inject() non constructor DI
@Service()
export class NotificationService {
  private readonly http = inject(HttpClient);
}

// injectAsync() — lazy loading di un servizio via dynamic import, con prefetch opzionale
const analytics = await injectAsync(() => import('./analytics.service'), { prefetch: 'onIdle' });

Angular Aria: Accessibility as Infrastructure

@angular/aria, now in general availability, provides directives that handle automatically ARIA attributes, keyboard navigation and focus management for composed patterns (combobox, tab, tree) — the developer focuses on visual design and business logic, not on manually reimplementing the ARIA Authoring Practices Guide for each component.

Breaking Changes and Deprecations

  • TypeScript 6 required: 5.9 and earlier are no longer supported — update TypeScript before running ng update.
  • Node 20 removed: Minimum supported is Node 22 (Node 26 supported).
  • touched in Signal Forms changed: from model to input/output pair (touched input, touch() output) — direct impact on the code that read/wrote touched as model.
  • markAsTouched() now marks descendants by default: use { skipDescendants: true } to preserve the previous behavior if your code assumed it.
  • Router: canMatch requires a third mandatory parameter (currentSnapshot) — existing guards must be updated in the signature.
  • paramsInheritanceStrategy now 'always' by default (was 'emptyOnly'): Check if your routing depended on the old implicit behavior.
  • Optional chaining in templates changes semantics: project?.author now returns undefined instead of null on null values, aligning with TypeScript.
  • withIncrementalHydration() deprecated because it is now the default SSR; use withNoIncrementalHydration() if you explicitly need the old behavior.

Tooling and Build

# Migrazione automatica dei test da Karma a Vitest
ng generate migrate-karma-to-vitest

# Build con ottimizzazione dei chunk abilitata di default (disattivabile via env var)
NG_BUILD_OPTIMIZE_CHUNKS=false ng build --configuration production

Rollup remains the default optimizer, but Rolldown is available as an option through NG_BUILD_CHUNKS_ROLLDOWN for those who want to experience further reduced build times. The PORT environment variable now takes precedence over the --port flag for the dev server, useful for containerized CI/CD setups.

Performance and Bundle

OnPush as default reduces the number of unnecessary change detection cycles already to start from new scaffolded projects, without the need for manual configuration. The optimization of chunk enabled by default in the production build further reduces the initial bundle compared to previous versions. Always measure before/after with standard instruments:

ng build --configuration production --stats-json
npx webpack-bundle-analyzer dist/*/stats.json
npx lighthouse http://localhost:4200 --view

State Management and Reactivity

With Signal Forms and Resource API both stable, the recommended pattern for new code is now Signal-first: local state with signal()/computed(), data fetching with resource()/httpResource(), form with Signal Forms. RxJS remains fully supported and necessary for complex streams (WebSockets, multiple combined events), but is no longer the implicit default for each new component. Experimental newness in this version: debounced(), a function that creates a debounced version of a Signal returning a Resource object.

// debounced() — sperimentale, debounce di un Signal senza RxJS
const query = signal('');
const debouncedQuery = debounced(query, { delay: 300 });

Server-Side Rendering and Edge

Incremental hydration is now the default SSR behavior (no longer opt-in via withIncrementalHydration(), which in fact is deprecated precisely because it is superfluous). provideServerRendering() now accepts an options object, including maxResponseBodySize to limit the size of the server-side rendered response — useful on edge platforms with stringent payload limits per single function.

// provideServerRendering con opzioni — utile su piattaforme edge con limiti di response size
provideServerRendering({ maxResponseBodySize: 5_000_000 });

Compatibility and Dependencies

AngularTypeScriptNodeNote
215.6+20 / 22Zoneless default, Experimental Signal Forms
226.0 minimum22 / 26 (20 removed)Signal Forms/Resource API/Aria stable

For Angular Material, NgRx and other ecosystem libraries, always check compatibility declared in the peerDependencies of the specific package before upgrading: npm view @angular/material peerDependencies. Libraries that depend heavily on Traditional FormControl/FormGroup remain compatible — Signal Forms coexists with legacy reactive/template-driven APIs, does not forcefully replace them.

Migration and Operational Plan

# Verifica prima di aggiornare
ng version
npm outdated

# Aggiornamento a v22 con dry-run preventivo
ng update @angular/core@22 @angular/cli@22 --dry-run
ng update @angular/core@22 @angular/cli@22

Minimum pre-upgrade checklist: TypeScript already at 6.x, Node already at 22+, dedicated branch, build and test green as baseline. After the update, run the entire test suite and a complete production build before proceeding with any optional adoption (Signal Forms, Aria) on existing components — the Version upgrades and the adoption of new APIs are two distinct activities, they should not be combined in one same commit. For rollback, the pre-upgrade Git tag remains the fastest and most reliable mechanism.

Testing and QA

// TestBed.getLastFixture() — nuova utility per recuperare l'ultima fixture creata
it('renderizza correttamente', () => {
  TestBed.createComponent(WidgetComponent);
  const fixture = TestBed.getLastFixture();
  expect(fixture.nativeElement.textContent).toBeTruthy();
});

Vitest now has native support for Zone.js via zone.js/plugins/vitest-patch, and the automatic migration migrate-karma-to-vitest covers most Karma projects existing; for those who have already migrated to Jasmine/Vitest, the flag --fake-async on migration refactor-jasmine-vitest covers timer-based asynchronous test patterns.

Security and Best Practices

No default changes related to cookies or CSP in this specific release, but the change to Fetch API for HttpClient is worth checking out: if your application depends on behaviors specific to XMLHttpRequest (e.g. custom headers on cross-origin requests), explicitly test i authentication flows after upgrade. The remaining best practices (HttpOnly/SameSite on cookies session, restrictive CSP) do not change and must be maintained regardless of the Angular version.

Use Cases

Case 1: Enterprise Dashboard with Complex Forms

An enterprise dashboard with over 40 forms distributed across various modules has adopted Signal Forms sui new feature forms after upgrading to v22, keeping legacy forms on traditional reactive forms thanks to the full coexistence of the two APIs. Result: boilerplate reduced by around 30% on new ones form, validation with native debounce which eliminated custom handwritten debounce code on RxJS previously.

Case 2: App with Stringent Accessibility Requirements

A public application subject to WCAG AA requirements has replaced the custom implementation of combobox and tab (with manually written ARIA management) with @angular/aria after the stabilization in v22. Result: Automatic accessibility audit passed without manual intervention addition on migrated patterns, reduction of specific focus/keyboard management code for component of approximately 200 lines in total.

FAQ

Do you need to immediately migrate all forms to Signal Forms?

No, Signal Forms coexists with legacy reactive/template-driven forms; migration can be gradual and opportunistic.

Does OnPush as default break existing components?

No, the default only applies to new components without explicit changeDetection; existing components maintain the already declared strategy.

Should I upgrade Node before upgrading Angular?

Yes, Node 20 is no longer supported in v22 - please check and update Node to 22+ before running ng update.

Does Fetch API by default break existing HTTP calls?

In most cases no, but check the upload progress reporting, which requires the new dedicated options instead of the old reportProgress.

Angular Aria replaces Angular Material?

No, they are complementary: Aria provides behavioral accessibility patterns, Material provides already stylized visual components.

What happens if I don't upgrade TypeScript to 6?

ng update to v22 will fail or report incompatibility: TypeScript 6 is a mandatory requirement, not optional.

Does Vitest necessarily replace Karma?

Not immediately required, but Karma is being deprecated in the Angular ecosystem; automatic migration makes switching to Vitest low risk.

Is AI/MCP tooling necessary to use Angular 22?

No, it is optional and designed for those who use AI-assisted coding agents; does not impact the standard operation of the application.

How to Check

  • Check version and dependencies: ng version and npm outdated.
  • Full production build: ng build --configuration production.
  • Run the entire test suite: ng test (or vitest run if already migrated).
  • Manual smoke test on critical flows (auth, main forms) after upgrade.
  • Full E2E testing: npx cypress run or equivalent.
  • Check bundle size and performance: bundle analyzer plus npx lighthouse http://localhost:4200, compared with the pre-upgrade baseline.

Conclusion

Angular 22 does not introduce a paradigm shift so much as a consolidation: Signal-based APIs are born in previous versions (Signal Forms, Resource API) finally become stable and ready for production, the defaults move towards more performing patterns (OnPush, Fetch API), and a first arrives tooling layer designed for AI-assisted development. For most projects, upgrading from v21 is low risk if TypeScript and Node are already up to date; the adoption of new ones However, API remains optional and can proceed gradually after the version upgrade.

Do you want a detailed migration checklist for your project or an assessment of the upgrade effort? Request a technical audit: in a few hours of analysis it is possible estimate risks, breaking changes relevant to your codebase and adoption priorities for new APIs.

💬 Reader notes

0 notes

Write a note

Share your opinion, a suggestion or a compliment

Latest notes

No notes yet. Be the first to comment!