Skip to main contentSkip to footer

Angular 22: Signals, Stability and a More Explicit Framework
Production-ready signals, stable forms, and a more explicit framework direction

Angular 22 feels like a meaningful step forward rather than a dramatic reset. The framework continues to move towards a more explicit, signal-driven and performance-conscious model, while also graduating a number of previously experimental features to stable status. The release is not trying to impress through volume. Instead, it tightens the areas that matter most in real applications: state management, forms, accessibility, routing, templates, change detection, and the broader development toolchain.

Category:

javascript

Tags:

Share this article on:

Angular 22 logo with signal icons, framework technology visualization, tech blog style

Stable APIs for the modern Angular stack

The most significant story in Angular 22 is stability. Three important pieces of the modern Angular story are now production-ready: Signal Forms, Angular Aria, and the asynchronous reactivity APIs.

Signal Forms gives Angular a more declarative and composable approach to forms, and it fits naturally with the wider signals model. That matters because forms are one of the places where application complexity tends to accumulate quickly. A more reactive, strongly typed approach reduces boilerplate and makes the flow of state easier to follow.

import { Component, signal } from '@angular/core';
import { form, required, min, max, FormField } from '@angular/forms/signals';

@Component({
  selector: 'app-support-ticket',
  templateUrl: './app-support-ticket.html',
  imports: [FormField],
})
export class SupportTicketComponent {
  readonly ticketModel = signal({
    issueType: '',
    impactScore: 1,
  });

  readonly ticketForm = form(this.ticketModel, schema => {
    required(schema.issueType, {
      message: 'Please categorize your issue before submitting',
    });
    min(schema.impactScore, 1);
    max(schema.impactScore, 5);
  });
}
<form>
  <label for="issue-category">Issue Category:</label>
  <select id="issue-category" [formField]="ticketForm.issueType">
    <option value="">Choose a category...</option>
    <option value="bug">Defect / Bug Report</option>
    <option value="feature">Feature Request</option>
    <option value="billing">Account & Billing</option>
  </select>

  @if (ticketForm.issueType().invalid() && ticketForm.issueType().touched()) {
  <p class="alert-text">
    @for (err of ticketForm.issueType().errors(); track err.kind) {
      <span>{{ err.message }}</span>
    }
  </p>
  }

  <label for="impact">Impact Score (1-5):</label>
  <input id="impact" type="number" [formField]="ticketForm.impactScore" />

  <button type="submit" [disabled]="ticketForm().invalid()">File Ticket</button>
</form>

Angular Aria is also now stable, which is an important step for teams building accessible component libraries and design systems. It gives Angular a clearer story for building accessible primitives without making every component author solve accessibility from first principles.

The async reactivity APIs, including resource, rxResource, and httpResource, are now stable as well. This is a particularly useful milestone because it means Angular now has a production-ready way to model asynchronous data in the same reactive style as the rest of the framework.

New APIs that improve day-to-day ergonomics

Angular 22 also introduces a new @Service decorator and injectAsync. Both are part of Angular’s ongoing effort to reduce boilerplate and make dependency management more intentional.

@Service gives a cleaner way to express the common singleton service case. injectAsync supports asynchronous dependency injection, which can help with lazy loading and code splitting for larger services or features. Taken together, these changes show Angular becoming more deliberate about how services are declared and consumed.

import { Service, injectAsync, Component } from '@angular/core';

@Service()
export class CommandHistory {
  private history: string[] = [];

  recordCommand(cmd: string): void {
    this.history.push(cmd);
  }

  getHistory(): string[] {
    return [...this.history];
  }
}

@Component({
  selector: 'app-terminal',
  template: `<button (click)="execute()">Run Script</button>`,
})
export class TerminalComponent {
  private runner = injectAsync(() => import('./script-runner'));

  async execute() {
    const scriptRunner = await this.runner();
    scriptRunner.execute();
  }
}

Runtime defaults are becoming more opinionated

One of the more important framework-level changes in Angular 22 is the shift in change detection defaults. OnPush is now the default for new applications, while the old default strategy is now referred to as Eager.

That is a significant change because it pushes new applications towards a more explicit rendering model from the outset. For teams building large applications, this is usually a positive move. It helps reduce accidental work, encourages clearer state flow, and aligns well with the broader signals direction.

import { ChangeDetectionStrategy, Component } from '@angular/core';

@Component({
  selector: 'app-legacy-telemetry',
  template: `<p>Processing real-time stream data...</p>`,
  changeDetection: ChangeDetectionStrategy.Eager,
})
export class LegacyTelemetryComponent {}

Template syntax becomes more expressive

Angular 22 also improves the template experience in practical ways. Comments are now supported inside HTML elements, spread syntax is available in templates, and inline arrow functions can be used where they help express a small piece of logic clearly.

The @switch block also becomes more capable, with support for multiple cases sharing the same block and exhaustive checks for union types. These are not headline features, but they are the kind of improvements that make templates less awkward to write and easier to maintain.

<section>
  @switch (incidentPriority) {
    @case ('Low')
    @case ('Medium') {
      <span class="toast-blue">Standard SLA Queue</span>
    }
    @case ('Critical') {
      <span class="toast-red">Immediate Escalation Required!</span>
    }
    @default {
      <span class="toast-gray">Unclassified Log Entry</span>
    }
  }
</section>
<section>
  <div [class]="{
    ...baseNotificationStyles,
    'pulse-animation': isUnread
  }"></div>

  <app-alert-center [silencedIds]="[...activeMutes, 'node-failure-01', 'disk-warning-02']"></app-alert-center>

  <button (click)="alert.update(a => ({ ...a, acknowledgementCount: a.acknowledgementCount + 1 }))">
    Acknowledge Incident
  </button>
</section>

Router, SSR and HTTP updates

Angular 22 also continues to refine routing and server rendering. The router gains platform Navigation API integration and more precise route cleanup controls. That points to a framework that is trying to align more closely with the browser while improving control over resource cleanup and navigation behaviour.

On the SSR side, incremental hydration is now the default. That is worth reviewing in any server-rendered application because hydration strategy affects startup behaviour and interaction timing. It is another example of Angular moving towards more progressive and efficient runtime defaults.

HTTP also changes in ways that matter in real applications. If your app depends on upload progress through XHR, you now need to opt in explicitly with provideHttpClient(withXhr()). The reportProgress option is also being deprecated in favour of more explicit upload and download progress options.

Agentic tooling and the broader Angular ecosystem

Angular 22 is also notable for how seriously it treats agentic development, and it has become a major strategic direction for the framework. The official release includes updates to MCP tooling, new Angular Agent Skills, Contributor Skills, and experimental WebMCP. Even if you are not using these directly yet, they are worth paying attention to because they show where Angular expects the developer workflow to go.

This is not a side note. It is part of Angular’s broader effort to stay relevant in a world where coding assistants and browser-based development tools are increasingly part of the workflow.

Upgrade notes

If you are moving from Angular 21 to 22, start with:

ng update @angular/core@22 @angular/cli@22

If you use Angular Material, also run:

ng update @angular/material@22

The main things to review are Node.js and TypeScript compatibility, stricter template diagnostics, the new OnPush default, the Eager rename, router behaviour changes, SSR hydration, and any removed or deprecated APIs. The official migration guide is here:

https://angular.dev/update-guide?v=21.0-22.0&l=3

Final thoughts

Angular 22 is a release that improves Angular where it matters most. It makes the framework’s modern direction more stable, more explicit, and easier to adopt in production. The benefit is not only new features, but a clearer overall shape to the framework.

For teams already using modern Angular patterns, this release should feel like a natural step forward. For teams still carrying older assumptions, it is a good moment to modernise with intent.