Angular 22.1: What's new
Angular 22.1 improves reactivity, styling, SSR and developer tooling while delivering faster builds with OXC.
đď¸ Framework
Core & Reactivity
a) Custom set option for linkedSignal - PR
linkedSignal now accepts a custom set callback. It lets you redirect writes to the original source signal instead of replacing the linked signalâs internal value.
Consider a temperature value stored in Celsius but displayed and edited in Fahrenheit:
import { linkedSignal, signal } from '@angular/core';
const tempC = signal(0);
const tempF = linkedSignal(
() => (tempC() * 9) / 5 + 32,
{
set: (valueF: number) => {
tempC.set(((valueF - 32) * 5) / 9);
},
},
);
console.log(tempF()); // 32
tempF.set(212);
console.log(tempC()); // 100
console.log(tempF()); // 212Calling tempF.set(212) redirects the update to tempC. Since tempF depends on tempC, it recalculates automatically and the reactive graph remains consistent.
The callback also receives a second argument called rawSet. You can use it when you need to update the linked signal directly and preserve its original write behavior.
const value = linkedSignal(source, {
set: (
newValue: number,
rawSet: (value: number) => void,
): void => {
if (shouldUpdateSource(newValue)) {
source.set(newValue);
} else {
rawSet(newValue);
}
},
});This is useful for editable derived values, form-like state and properties extracted from larger parent signals.
Templates & Compiler
a) CSS Variable Namespacing - PR
Running multiple Angular applications on the same page can cause CSS variables to leak between them. One application may set --primary-color, and another embedded application can accidentally inherit it.
Angular 22.1 introduces CSS variable namespacing for component styles:
import {
APP_ID,
ApplicationConfig,
} from '@angular/core';
import { provideCssVarNamespacing } from '@angular/platform-browser';
export const appConfig: ApplicationConfig = {
providers: [
{
provide: APP_ID,
useValue: 'storefront',
},
provideCssVarNamespacing('storefront_'),
],
};You can continue writing regular CSS variables:
:host {
--primary-color: blue;
color: var(--primary-color);
}Angular transforms them using the configured namespace:
:host {
--my-app_primary-color: blue;
color: var(--my-app_primary-color);
}Only styles declared through styles or styleUrls in Angular components are transformed. Global stylesheets remain unchanged.
Variables beginning with --global-- are deliberately excluded:
:host {
--global--shared-spacing: 16px;
}Template bindings such as [style.--highlight] are also namespaced. Code that accesses variables programmatically should use CssVarNamespacer, especially in libraries where the consuming application may enable namespacing.
b) Smaller generated output for foreign componentsâââPR
The compiler no longer emits a redundant tag name when a foreign component is the root of an @if, @for or @switch block.
This is a small internal performance improvement that reduces generated output without requiring application changes.
HTTP
a) More control over the HTTP transfer cache - PR
Angularâs HTTP transfer cache stores server responses during SSR so the browser doesnât immediately request the same data again during hydration.
Angular 22.1 adds two options:
includeRequestsWithCredentialsincludeNonCacheableRequests
import { ApplicationConfig } from '@angular/core';
import {
provideClientHydration,
withHttpTransferCacheOptions,
} from '@angular/platform-browser';
export const appConfig: ApplicationConfig = {
providers: [
provideClientHydration(
withHttpTransferCacheOptions({
includeRequestsWithCredentials: true,
includeNonCacheableRequests: true,
}),
),
],
};includeRequestsWithCredentials allows requests using withCredentials or Fetch credential modes to enter the transfer cache.
includeNonCacheableRequests permits requests and responses normally excluded by Cache-Control, Set-Cookie or Fetch cache options.
Both options default to false. Enable them only when the response is safe to serialize into the server-rendered pageâparticularly when SSR output might be cached or shared.
b) â ď¸ JSONP support is deprecatedâââPR
Angular has deprecated JSONP because it executes arbitrary scripts in the global context. This can bypass modern Content Security Policies and introduce cross-site scripting risks.
The deprecation covers:
HttpClient.jsonp()HttpClientJsonpModuleJsonpClientBackendJsonpInterceptorjsonpInterceptorFnjsonpCallbackContextwithJsonpSupport()
// Before â
this._http.jsonp<DataResponse>(
âhttps://api.example.com/dataâ,
âcallbackâ,
);
// After â
this._http.get<DataResponse>(
âhttps://api.example.com/dataâ,
);Remove withJsonpSupport() from your HTTP providers as part of the migration.
If an external API only supports JSONP, use a backend proxy or move to an endpoint supporting CORS. Angular intends to remove JSONP in a future version.
Router
a) Nullable inputs for RouterLinkActive - PR
RouterLinkActive now accepts null and undefined for both routerLinkActive and routerLinkActiveOptions.
Reusable link components previously needed duplicated @if branches when active styling was optional. The directive can now remain in one template:
<a
[routerLink]=âhref()â
[routerLinkActive]=âactiveClass()â
[routerLinkActiveOptions]=âactiveOptions()â
>
<ng-content />
</a>The behavior depends on the input:
routerLinkActive: null | undefinedapplies no active classes.routerLinkActiveOptions: undefineduses the default subset match.routerLinkActiveOptions: nulldisables active matching.
That means fewer conditional branches and fewer unnecessary comment nodes in reusable navigation components.
Language Tooling
a) Compile non-exported classes if standalone - PR
The Angular Language Service now compiles standalone classes that arenât exported from their file. Previously, if you had a component that wasnât exported (common in single-file route components or test files), the language service would skip it â meaning no autocompletion, no type-checking, no diagnostics in your template.
b) Typecheck templates requiring inline typecheck blocks - PR
Part of the same PR â the language service can now type-check templates that would require inline type-check blocks. Previously, certain template patterns that the compiler couldnât handle with external type-check files were simply skipped by the language service. Now they get full diagnostics.
Developer Tooling
a) Deep linking from Chromeâs Performance panel - PR
Angular component events recorded in Chromeâs Performance panel can now link directly to the corresponding component inside Angular DevTools.
The recorded event contains a URL using this format:
angular-devtools://component/{instanceId}Selecting it opens that specific component instance in Angular DevTools, making it easier to move from a performance problem to the component responsible for it.
The integration currently depends on Chromeâs DevTools extensibility support and may require enabling:
chrome://flags/#enable-devtools-deep-link-via-extensibility-apiđ ď¸ CLI & Build Tooling
a) Angular MCP server enabled by default in new workspaces - PR
The ai-config schematic now includes Angular MCP server configuration.
New workspaces created with AI configuration can connect supported AI tools to Angularâs development capabilities with less manual setup.
b) â ď¸ Deprecation of stringToFileBuffer and fileBufferToString in @angular-devkit/core
stringToFileBuffer and fileBufferToString from @angular-devkit/core are now deprecated. The replacement is the standard Web APIs: TextEncoder and TextDecoder.
// Before â
import { stringToFileBuffer, fileBufferToString } from '@angular-devkit/core';
const buffer = stringToFileBuffer('hello');
const str = fileBufferToString(buffer);
// After â
const encoder = new TextEncoder();
const decoder = new TextDecoder();
const buffer = encoder.encode('hello');
const str = decoder.decode(buffer);c) Share Build Cache Across Git Worktrees - PR
Angular now shares its persistent build cache across Git worktrees belonging to the same repository.
Instead of creating a separate .angular/cache directory in every worktree, Angular resolves the cache from the main repository:
main-repository/
âââ .angular/cache/
âââ worktree-feature-a/
âââ worktree-feature-b/Regular repositories and Git submodules retain their existing behavior. If worktree detection fails, Angular safely falls back to the workspace-relative cache.
This reduces duplicated cache files and avoids rebuilding the same artifacts across parallel branches.
d) Chunk optimization for server builds â PR
Angular can now optimize browser chunks even when an application uses SSR or has a server entry point.
For those unfamiliar with OXC: itâs a collection of high-performance JavaScript and TypeScript tools written in Rust. Angular uses its fast parser to reduce build times, with no extra configuration required.
e) Faster production optimizations with OXC â PR
Angular moved several internal production optimizations from Babel to the faster OXC parser.
f) Much faster localized builds â PR
Angularâs localization worker now uses OXC and magic-string instead of Babel.
đŚ Migrations & Schematics
a) @Injectable to @Service migration schematic - PR
Angular now ships an automated migration schematic that converts eligible @Injectable classes to the new @Service decorator. This is part of the broader push toward more semantic decorators â @Service communicates intent more clearly than @Injectable, which was always a bit of a misnomer (it describes how the class participates in DI, not what it is).
Run it with:
ng generate @angular/core:serviceOr target a specific directory:
ng generate @angular/core:service --path src/app/featuresWhat it does:
// Before â
import { Injectable } from '@angular/core';
@Injectable({ providedIn: 'root' })
export class UserService {}// After â
import { Service } from '@angular/core';
@Service()
export class UserService {}The schematic handles the import swap automatically â replacing Injectable with Service in the import statement and updating the decorator call.
Limitations â the schematic will skip classes that:
Use constructor-based dependency injection (since
@Serviceis designed for theinject()pattern)Pass any options into
@Injectableaside fromprovidedInPass anything aside from
'root'intoprovidedIn
This is conservative by design. The schematic wonât touch classes using useFactory, useClass, useValue, or useExisting providers, nor will it touch services scoped to specific modules or components. Those cases require manual review.
If youâre already following modern Angular patterns (using inject() instead of constructor injection, providing services at root), this migration should cover the vast majority of your services with zero manual intervention.
â ď¸ Breaking Changes & Deprecations
1. JSONP Support Deprecated (@angular/common/http)
HttpClient.jsonp, HttpClientJsonpModule, withJsonpSupport(), and all related JSONP classes/functions are deprecated due to XSS vulnerability risks. Use standard HTTP requests with CORS instead. Intent to remove in a future Angular version.
PR: #69116
2. stringToFileBuffer and fileBufferToString Deprecated (@angular-devkit/core)
These utility functions are deprecated in favor of standard Web APIs (TextEncoder and TextDecoder). Internal usages have already been removed and replaced.
Thanks for reading so far đ
Iâd like to have your feedback, so please leave a comment, clap or follow. đ
Spread the Angular love! đ
If you liked it, share it among your community, tech bros and whoever you want! đđĽ
Donât forget to follow me and stay updated: đą
đ LinkedIn
đ Medium
đĽ YouTube
đŚ Twitter
Thanks for being part of this Angular journey! đđ


