Angular 22 and the Signal-First Era: A Field Guide for Teams on Older Versions

Eric Greene June 11, 2026

Angular 22 shipped on June 3, 2026, and it is the clearest statement yet of where the framework has been heading since signals first appeared: the signal-first era is no longer experimental, optional, or "coming soon." It is the default. We teach a lot of teams whose production code is still on Angular 12, 14, or 16, and the distance between what they maintain and what the framework now assumes has become large enough that it deserves a map. This post is that map.

What actually changed in 21 and 22

Two releases define the new baseline. Angular 21, released in November 2025 and designated LTS, made zoneless change detection the default for new projects. Zone.js — the monkey-patching layer that has powered Angular's "it just updates" magic since AngularJS days — is no longer part of a fresh application. Change detection is driven by signals and explicit notifications instead of patched browser APIs. Existing apps keep Zone.js until they opt out, but the framework's center of gravity has moved.

Angular 22 builds on that with four defaults worth knowing:

  • Signal Forms are stable. This is the first genuinely new forms model since reactive forms, built around a signal holding your data model, with schema-based validation and field state you read like any other signal. Reactive and template-driven forms still work, but Signal Forms are where investment is going.
  • Vitest is the default test runner. Karma — deprecated for years — is out of the default experience, and the experimental Jest and Web Test Runner integrations were removed in favor of one supported path. Migration tooling exists, but if you have thousands of Karma/Jasmine specs, this is a real workstream.
  • OnPush is the default change detection strategy for newly generated components. This only affects what ng generate writes, but it signals (no pun intended) the expectation: components declare their dependencies via signals and inputs, and the framework checks them only when something they depend on changed.
  • strictTemplates is on by default for new projects, which catches the template type errors that older codebases discover at runtime.

None of this breaks an existing app on day one. All of it changes what "idiomatic Angular" means, what documentation assumes, and what new hires expect.

The upgrade path is a ladder, not an elevator

The most important planning fact: Angular's supported migration path is one major version at a time via ng update. There is no sanctioned jump from 14 to 22. A team on Angular 14 is looking at eight sequential updates, each of which is individually small — the Angular team's update tooling and the update guide are genuinely good — but which add up to real calendar time when you fold in regression testing.

Our practical advice: do not schedule "the big upgrade" as one heroic quarter. Schedule a steady cadence — one major version per sprint or two is realistic for a mid-sized app — and keep shipping features on the same branch. The versions between you and 22 each deprecate things gently before the next one removes them, so moving stepwise is also how you get the deprecation warnings while they are still warnings.

The three modernizations that matter most

Inside that climb, three transitions account for most of the work, and all three have official schematics that do the bulk of it.

NgModules to standalone. Standalone components became the default back in v17, and ng generate @angular/core:standalone converts existing modules in three passes — convert components, remove unnecessary NgModules, bootstrap standalone. In our experience the schematic handles 85–90% of a typical app; the leftovers are usually router configuration and testing modules.

Structural directives to built-in control flow. *ngIf, *ngFor, and *ngSwitch give way to @if, @for, and @switch blocks via ng generate @angular/core:control-flow. This one is nearly free, and @for's mandatory track expression routinely fixes performance problems teams did not know they had — we have watched list re-render times drop noticeably on apps that had been silently re-creating DOM for years.

RxJS-based state to signals. This is the judgment-call migration, and the place teams most need a rule of thumb. Ours: signals for state, RxJS for events. A BehaviorSubject holding the currently selected customer, combined through combineLatest into a view model, becomes dramatically simpler as a signal plus computed. But a debounced typeahead, a websocket stream, a retry-with-backoff HTTP flow — those are event streams over time, and RxJS remains exactly the right tool. Do not let anyone tell you signals replace RxJS wholesale; the codebases that try end up reimplementing operators badly. The interop functions (toSignal, toObservable) let the two worlds meet cleanly at the boundary. The state side of that split is pleasantly small:

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

@Component({
  selector: 'app-cart-summary',
  template: `<p [textContent]="summary()"></p>`,
})
export class CartSummary {
  readonly prices = signal<number[]>([19, 42, 7]);
  readonly count = computed(() => this.prices().length);
  readonly total = computed(() => this.prices().reduce((s, p) => s + p, 0));
  readonly summary = computed(() => `${this.count()} items — ${this.total()} total`);
}

Why bother, concretely

The payoff for landing on 21 or 22 is not abstract modernity. Zoneless change detection removes a whole class of "why did this run change detection 400 times" performance mysteries and makes stack traces readable again. OnPush-by-default plus signals means the framework does provably less work per interaction. Vitest runs the same specs in a fraction of Karma's time, which compounds across every CI run. And strictTemplates plus typed forms move a category of production incidents into compile errors. Teams we have helped through this consistently report that the post-migration codebase is smaller — control flow blocks are terser than structural directives, standalone components delete module boilerplate, and signal-based view models delete subscription management.

The signal-first era rewards teams that move deliberately: one version at a time, schematics first, RxJS kept where it belongs. If your team is staring up this ladder from Angular 12–16, our Modernizing Legacy Angular course walks through exactly this migration on a real legacy codebase, and Mastering Angular covers signal-first architecture, Signal Forms, and zoneless change detection for teams building on the current platform.