At Google I/O, Angular 20 was announced and now is officially released, bringing innovations that promise to transform the frontend development experience. This latest version represents another major milestone in Angular’s evolution toward a faster, more reactive, and developer-friendly ecosystem.
With Angular 20, the development team has finally stabilized some of the community’s most requested features. From performance gains with “zoneless” mode (now in preview) to new APIs for handling asynchronous data, this release signals the start of a new chapter for Angular.

Signals: the reactive heart of Angular
Signals continue to be the cornerstone of Angular’s new reactive architecture. Introduced as experimental features in versions 16, they now represent the foundation for building modern, performant applications and will form the basis of this framework’s future direction.
One of the most significant updates is that linkedSignal
has become stable. A linkedSignal
is a special type of writable signal in Angular. Its distinctive characteristic is that it’s “linked” to one or more source signals. This means:
- Its initial value is derived from one or more signals
- It stays synchronized: When any source signal’s value changes, the
linkedSignal
automatically “resets” to the newly value - It’s writable: Unlike a
computed
(which is read-only), you can manually modify alinkedSignal
‘s value using the.set()
or.update()
methods. This manual modification is temporary: if the source signals change again, thelinkedSignal
will revert to the calculated value.
In general, signals offer more intuitive state management compared to RxJS Observables for many common use cases. The main advantages include simpler syntax and better performance (they’re essentially primitives, eliminating all the dependency overhead).
// Base Signal
const counter = signal(0);
// Derived Signal
const doubledCounter = computed(() => counter() * 2);
// linkedSignal - now stable!
const userPreferences = signal({ theme: 'light', language: 'it' });
const currentTheme = linkedSignal(() => userPreferences().theme);

Resource, httpResource, and Streaming Resource
Angular 20 introduces three fundamental new APIs for managing asynchronous operations, each optimized for specific use cases (in v19 these are experimentals).
Resource API
The resource()
is perfect for promise-based asynchronous operations:
const searchQuery = signal('');
const searchResults = resource<User[], string>({
request: () => searchQuery(),
loader: async ({ request, abortSignal }) => {
const response = await fetch(`/api/users?q=${request}`, {
signal: abortSignal
});
return response.json();
}
});
// Template usage
// searchResults.value() -> data
// searchResults.isLoading() -> loading state
// searchResults.error() -> any errors
httpResource API
httpResource()
integrates natively with Angular’s HttpClient:
const userId = signal(1);
const userProfile = httpResource<User>({
url: computed(() => `/api/users/${userId()}`),
loader: (url) => this.http.get<User>(url)
});
Streaming Resource
For operations requiring real-time updates, such as using an AI service that provides responses progressively:
const liveData = streamingResource({
request: () => signal('live-feed'),
loader: ({ request }) => {
return new EventSource(`/api/stream/${request()}`);
}
});

Zoneless in developer preview
One of the hottest features in Angular 20 is zoneless mode, now available in developer preview. This functionality represents a fundamental paradigm shift in how Angular handles DOM change detection.
What’s changing
Traditionally, Angular used Zone.js to automatically intercept all asynchronous operations and trigger change detection. The main issue is that DOM updates occur even when unnecessary, in response to every browser event. Zoneless mode eliminates this dependency, giving developers direct control over when and how the interface updates (with signals that tell to the framework where perform update). The goal is for the DOM to update only where data has actually changed, avoiding unnecessary calculations and improving performance.
Why it was introduced
The main reasons include:
- Better performance: Elimination of Zone.js overhead
- Lighter bundles: Removal of a significant dependency
- Simplified debugging: Cleaner, more understandable stack traces
- Improved compatibility: Works better with modern APIs and third-party libraries
Zoneless mode is particularly powerful when combined with signals, which provide a natural mechanism for notifying state changes.
Server Side Rendering and Incremental Hydration
Angular 20 brings significant improvements to Server Side Rendering (SSR) with the introduction of Incremental Hydration as a stable feature.
Incremental Hydration
This technique allows selective “hydration” of application parts, dramatically improving initial loading times.
@Component({
template: `
<div>
<h1>Contenuto statico</h1>
@defer (on viewport) {
<heavy-component />
}
</div>
`
})
export class PageComponent {}
Incremental Hydration allow to the page to be pre-rendered on server and sent to the client. The avantages are:
- 40-50% improvement in Largest Contentful Paint (LCP)
- Faster loading of critical application parts
- Better SEO through optimized server-side rendering (without pre- rendering the page sent to client is empty)
- Superior user experience with immediately visible content
Standalone components: the present and future standard
Standalone Components have now become the standard for Angular development and clearly represent the framework’s future. This was already known but has been further emphasized.
The advantages include:
- Simplified syntax: Elimination of NgModules for many use cases
- Smaller bundles: Selective importing of dependencies, not entire modules
- Improved Developer Experience: Less boilerplate and configuration
@Component({
selector: 'app-user-card',
standalone: true,
imports: [CommonModule, RouterModule], // <- Use import with standalone
template: `
<div class="user-card">
<h3>{{ user().name }}</h3>
<p>{{ user().email }}</p>
</div>
`
})
export class UserCardComponent {
user = input.required<User>();
}
Testing: three competing solutions
With Karma’s deprecation, Angular 20 introduces a new testing approach with three experimental solutions for the community to choose from:
1. Jest (Testing Node.js)
Optimized for fast unit tests:
ng test --runner=jest
2. Web Test Runner (Testing Browser)
Specialized for tests requiring a real browser environment:
ng test --runner=web-test-runner
3. Vitest (Testing Ibrido)
Modern solution supporting both Node.js and browser:
ng test --runner=vitest
IMPORTANT: Jasmine remains the assertion library, ensuring no breaking changes for existing tests. The final choice will depend on community feedback and performance observed in the coming months.

Enhanced Firebase Integration
Angular 20 introduces significant improvements in Firebase integration, making it simpler and more intuitive to develop applications using Google Cloud services.
The new APIs offer:
- Native integration with signals for real-time database
- Improved support for Authentication and Firestore
- Simplified configurations and initial setup
Angular.dev/ai: AIbest practice
An interesting addition is the creation of a new section at http://angular.dev/ai, dedicated entirely to best practices for integrating Artificial Intelligence functionality into Angular applications.
This resource provides:
- Guidelines for AI API integration
- Design patterns for AI-friendly interfaces
- Practical implementation examples
- Performance and user experience considerations
This is a clear signal of how Angular is positioning itself for the future of web development, where AI will play an increasingly central role.
Roadmap: the future lies in Signals
The roadmap for Angular 20 and beyond clearly shows two main priorities:
1. Improved Developer Experience
- More intuitive CLI tools
- Enhanced debugging
- Updated documentation and tutorials
- Deeper IDE integration
2. Framework Performance
- Continuous runtime optimizations
- Better change detection algorithms
- Reduced bundle size
- Faster build times
Signal Forms: The Next Big Step
One of the most anticipated features is the introduction of Signal Forms, which will revolutionize form handling in Angular:
// Signal Forms preview (experimental)
const userForm = signalForm({
name: signalControl(''),
email: signalControl('', [validators.email]),
age: signalControl(0, [validators.min(18)])
});
// Automatic reactivity
const isValid = computed(() => userForm.valid());
const formData = computed(() => userForm.value());
Conclusions
The path to Angular’s future is clear: more performance, more simplicity, and more control for developers. Angular 20 is just another step in a revolution that began several versions ago.
The introduction of zoneless mode in developer preview, the stabilization of Resource APIs, and the consolidation of Standalone components demonstrate how Angular is evolving toward a more modern and performant ecosystem.
Angular’s future is clearly oriented toward signals as the fundamental primitive for reactivity. For those who haven’t yet started exploring these new features, now is the perfect time to begin.
But what about existing complex applications that don’t leverage Signals? That’s a great question, and each case will need to be evaluated individually. RxJS events aren’t something to throw away—they work well and have enabled us to build enterprise-level applications. It’s clear that the framework’s future will be based on Signals, so where possible (new features/refactoring), it makes sense to develop using these new primitives, especially considering they should be more performant.
Finally, here’s the link if you missed the Google I/O ’25 live stream where all this was discussed!
Thanks for reading, see you next time!
Giorgio