Signals, Zoneless, declarative async resources: Angular 22 makes standard several features that help developers build better apps.
A few days ago, we checked out Google I/O 2026, and today we need to talk about our favorite framework: Angular. Why? Because version 22 is here!
Angular v22 is a major update focused on stability, performance and ergonomic APIs. It brings a more polished signal-driven platform and better data loading primitives that make modern apps feel faster and simpler to build.
Before we look at the most interesting changes, let’s talk about the foundation. Angular v22 stabilizes the features we have been testing in the last few versions. If you want to build a high-performance app today, these are the new standards.
Reactive Forms were great, but they often felt separate from the modern Signal-based reactivity. In v22, Signal Forms are officially stable.
What does this mean for us?
- Better reactivity: No more unnecessary updates when a single field changes.
- Better type safety: We finally have a form system that works perfectly with TypeScript.
Do you remember HttpClient and the manual toSignal conversions? They worked, but they added extra code. Now we have httpResource.
It is the new standard for fetching data. It treats your HTTP requests as signals, automatically handling the loading, error, and data states for you.
Learn more: Dive deeper into Getting Started with httpResource API and learn more about Angular Signal Forms vs. Reactive Forms.
But what if your request depends on another signal? In v22, we have the new chain() method. It allows you to link resources together. If the first resource is loading, the second one waits automatically. This is a big win for complex data!
Wait, what if you are already using RxJS? Don’t worry, Angular has a solution for that too. Let’s see how v22 handles the transition from Observables to Resources.
RxResource vs. httpResource
A common question is: “Should I stop using RxJS?” The answer is no. Angular v22 introduces rxResource as the perfect partner for your existing Observable streams.
httpResource: Use this for standard API calls. It is optimized for the Fetch API and handles JSON automatically.rxResource: Use this when your data source is an existing Observable. It allows you to use the power of RxJS operators inside the clean, Signal-based Resource API.
Now that we have our data fetching ready, how do we make sure our users and agents can navigate efficiently? Let’s talk about the new smart navigation features in the Router.
Smart Navigation and Incremental Hydration
The Angular Router received some updates in v22 that solve common problems.
- URL decoupling: You can now keep a clean URL in the address bar while the app shows a different state. With the new
browserUrl input on RouterLink, you can show /profile while the router actually uses /users/123. - Parameter inheritance: Child routes now inherit parameters from their parents by default, and you don’t need extra configuration to get an ID from a parent route.
But a great UI and smart routing mean nothing if the page is slow to load. This brings us to the most impressive performance update in v22: incremental hydration.
Server-Side Rendering (SSR) is no longer a problem. In v22, incremental hydration is the default.
Angular now loads your application in small parts as they become visible. Combined with resource caching, the client can use the data fetched on the server without making a second API call. The user sees the data instantly, and the “flicker” of reloading data is gone.
Learn more: Explore The New Angular Hydration for in-depth details.
But performance is also about how the browser handles changes. This is where the biggest change in Angular’s history reaches its peak.
Zoneless and OnPush by Default
For years, zone.js was the engine behind Angular’s change detection. With v22, Angular is now Zoneless by default.
By using ChangeDetectionStrategy.OnPush as the default for new components, we get:
- Smaller app sizes: We no longer need the heavy Zone.js library.
- Fast performance: The framework only checks what it needs to, exactly when it needs to.
If you have an older app, don’t worry! There is a migration tool that adds ChangeDetectionStrategy.Eager (the new name for the old behavior) so your app keeps working while you move to Signals.
Now, how do we make sure our fast code actually works? Let’s talk about the new speed king of testing.
Vitest
Testing used to be the slow part of our work. Not anymore. Angular v22 officially replaces Karma/Jasmine with Vitest as the default test runner.
It is very fast and shares the same configuration as your build pipeline. Also, the new migrate-karma-to-vitest tool makes the change very easy, even for complex tests!
Do you want to try Vitest?
Angular Aria: Accessibility for Everyone
Building custom components with correct ARIA roles and focus management can be difficult. In v22, Angular Aria is officially stable.
Think of it as “headless accessibility.” It provides the logic you need to build your own accessible components. It handles the complicated parts of ARIA attributes and keyboard interactions for you.
Why does this matter for AI? Because accessible apps are much easier for AI Agents to understand!
Check this example about how to build accessible components with Angular Aria.
Developer Experience & Safety
In v22, we finally have @boundary as part of the preview story. It is useful for future error-handling patterns. Here’s how @boundary works for error containment:
@Component({
selector: 'app-user-profile',
standalone: true,
template: `
<div>
<h2>User Profile</h2>
<p>{{ userData() }}</p>
</div>
`
})
export class UserProfileComponent {
userData = signal(null);
}
@Component({
selector: 'app-dashboard',
standalone: true,
imports: [UserProfileComponent],
template: `
<div>
<h1>Dashboard</h1>
@boundary on error {
<p>Failed to load user profile</p>
} {
<app-user-profile />
}
</div>
`
})
export class DashboardComponent {}
Selectorless Components
You no longer need a selector for a component that only lives in a route. It reduces extra code.
@Component({
standalone: true,
template: `<h3>I'm a lean, selectorless component!</h3>`
})
export class DetailViewComponent {}
Async Dependency Injection
The injectAsync() function allows us to load services only when they are needed. This keeps your app small and fast.
async onReportRequested() {
const analytics = await injectAsync(AnalyticsService);
analytics.track('report_viewed');
}
Building a Dashboard with Angular 22
Instead of just explaining features, let’s build a practical dashboard example that uses the stable core of Angular v22: @Service(), httpResource() and the new template syntax.
Want to follow along? You can clone the complete project from GitHub: angular-22-nba-finals. Just run npm start and you’ll have the dashboard running locally.
The Data Service with @Service
Now, let’s create our service. We will use the new @Service() decorator (which replaces @Injectable()) and httpResource to fetch the games. Notice how httpResource handles loading and error states for you.
import { Service } from '@angular/core';
import { httpResource } from '@angular/common/http';
export interface NbaGame {
id: number;
gameNumber: number;
homeTeam: string;
homeScore: number | null;
awayTeam: string;
awayScore: number | null;
status: 'Final' | 'Scheduled';
date: string;
location: string;
}
@Service()
export class NbaService {
gamesResource = httpResource<NbaGame[]>('/api/nba-finals');
}
The UI Layer & Error States
We display the data using the new @for block and keep the error handling inside the component template. This keeps the example focused on stable Angular v22 behavior.
@Component({
template: `
<app-dashboard></app-dashboard>
<router-outlet></router-outlet>
`
})
Our Dashboard component remains simple:
import { Component, inject } from '@angular/core';
import { NbaService } from './nba.service';
@Component({
selector: 'app-dashboard',
standalone: true,
template: `
<div class="dashboard">
<h1>NBA Finals 2026: Knicks vs Spurs</h1>
@if (nbaService.gamesResource.isLoading()) {
<p>Loading game data...</p>
} @else {
<div class="cards">
@for (game of nbaService.gamesResource.value(); track game.id) {
<div class="card">
<div class="meta">Game {{ game.gameNumber }} • {{ game.date }}</div>
<div class="score">
{{ game.homeTeam }} {{ game.homeScore }} vs {{ game.awayScore }} {{ game.awayTeam }}
</div>
<div class="status">{{ game.status }}</div>
</div>
}
</div>
}
</div>
`
})
export class DashboardComponent {
nbaService = inject(NbaService);
}
Save changes and run ng server navigate in the browser and tada!!!

Done!! We play with the stable part of Angular v22 using @Service() for a clean singleton service definition, httpResource() for declarative, signal-based HTTP loading and @for with @if in templates to render loading and data states.
And, of course, AI is not forgotten by the Angular team. They updated and added new tools for Angular MCP and Skills. Let’s see them!
Angular MCP and Skills
Of course, Angular continues embracing AI. The Angular MCP exposes app state and builds workflows for tools that understand Angular projects. That includes server-side MCP tools such as devserver.wait_for_build, devserver.start and devserver.stop.
Version 22 also introduces Agent Skills for Angular, a lightweight set of skill definitions that give AI assistants direct knowledge of modern Angular idioms and best practices. These skills are useful for teams that want to integrate agent-assisted coding into their workflow without pain.
Recap
Angular 22 is a declaration that the way we build for the web has evolved. And by using Signals, Zoneless performance and declarative async resources, we can build applications that are faster, simpler and easier to maintain.
This release is about making stable patterns:
- Use
httpResource() for fetch-heavy components. - Use
@Service() for singleton services. - Use
injectAsync() when you want to defer heavy service loading. - Let template syntax like
@for and @if keep your view code readable. - Embrace the AI era with Agent Skills and MCP tools.
My advice is don’t just read this article—build something! Take the dashboard we sketched and turn it into an interactive experience with Progress Kendo UI for Angular AI Chat. A chat interface is a powerful way to explore the series score in real time and it’s a great way to test Angular 22 with a modern Kendo UI scenario.
Feel free to watch for all the new features in Angular 22:
Happy coding!