All posts
Angular 20: stable Signals, Zoneless and more
Angular

Angular 20: stable Signals, Zoneless and more

Angular 20 brings a wide range of updates: improvements to reactivity, SSR, support for zoneless architecture, template syntax enhancements, better tooling, and more.

IKIgor Katsuba
4 minutes read

Below is a categorized breakdown of all the changes:

At the end, I’ll share some of my personal highlights 👇


✅ What's Stable Now

Reactivity

  • effect, linkedSignal, toSignal are now stable APIs.
  • incremental hydration and route-level rendering mode config have also reached stable status.

🧪 New but Still Unstable (Developer Preview / Experimental)

Zoneless (Developer Preview)

  • Promoted to Developer Preview.
  • Default error handlers for SSR (unhandledRejection, uncaughtException).
  • CLI now lets you create a project without Zone.js.

Reactive Resources (Experimental)

  • resource API to trigger async operations from signals.
  • streamingResource for working with WebSocket streams.
  • httpResource wraps HttpClient in a reactive, signal-based API.

Vitest Support (Experimental)

  • Alternative to Karma with watch mode and jsdom support.

✨ Brand New Features

Angular + AI

  • llms.txt file to help LLMs generate up-to-date Angular code.
  • Guides and demos for building AI-powered apps using Genkit and Vertex AI.

Official Angular Mascot

  • RFC opened for the official Angular mascot — voting and suggestions welcome.

🛠 Improvements

Developer Experience

  • Angular DevTools now shows @defer blocks, hydration state, and zones.
  • Chrome DevTools integration in the Performance tab.
  • Better template diagnostics: missing trackFn calls, ?? misuse, missing imports, etc.

createComponent Enhancements

  • Support for bindings, directives, and two-way binding.
  • Apply directives and bindings declaratively at component creation.

Template Syntax

  • Support for ** (exponentiation), in operator, and untagged template literals.

Host Bindings

  • Full type-checking and language service support for the host object.
  • New typeCheckHostBindings flag in tsconfig.json.

Updated Style Guide

  • Suffixes like Component, Service, Pipe are now optional.
  • Simplified structure and removed boilerplate.
  • Moved non-Angular specific practices to documentation.

⚠️ Deprecated and Should Be Avoided

Structural Directives

  • *ngIf, *ngFor, and *ngSwitch are now deprecated. New control flow syntax @if, @for, @switch is preferred. Migration command: ng generate @angular/core:control-flow

🌟 My Personal Favorites

Zoneless (Developer Preview)

I've often run into issues with Zone.js—from odd side effects during state updates to unpredictable behavior due to monkey-patching. On the server, it's even worse, causing memory leaks in Node.js and hard-to-trace crashes.

Now, you can bootstrap your app without Zone.js using:

bootstrapApplication(AppComponent, {
  providers: [
    provideZonelessChangeDetection(),
    provideBrowserGlobalErrorListeners()
  ]
});

Just make sure to remove the zone.js polyfill from angular.json. This greatly simplifies debugging and SSR stability.


createComponent API

Creating dynamic components used to be verbose. Now, it’s all declarative:

createComponent(MyDialog, {
  bindings: [
    inputBinding('canClose', signal(true)),
    outputBinding('onClose', (result) => console.log(result)),
    twoWayBinding('title', signal('Dialog Title'))
  ],
  directives: [FocusTrap]
});

This is a major improvement, especially for UI library authors. It unlocks powerful use cases. It is like host directives, but in runtime and dynamic.


Host Bindings

@HostBinding and @HostListener were convenient, but the main problem for me was that they don't work with signals and Observables. Now you can express this clearly in the host object with full editor support:

@Component({
  host: {
    '[class.active]': 'isActive()',
    '(click)': 'handleClick()',
  }
})

And now with typeCheckHostBindings enabled:

{
  "angularCompilerOptions": {
    "typeCheckHostBindings": true
  }
}

You get type safety and better DX.


Deprecation of *ngIf, *ngFor, *ngSwitch

This was long overdue. The new control flow syntax is simpler, closer to JavaScript, and removes the need to import CommonModule.

Migration is easy:

ng generate @angular/core:control-flow

From this:

<div *ngIf="user">{{ user.name }}</div>

To this:

@if (user) {
<div>{{ user.name }}</div>
}

Cleaner, more readable, fewer surprises.


🧾 Final Thoughts

This was a solid release. Of course, as developers, we always wish new features were stabilized faster and shipped more frequently — but that doesn't make us any less excited for the next major in six months or the RFCs in between.

Meanwhile, minor releases might still bring exciting updates. And yes, we’re looking at you, signal-based forms ✌️


🟢 Course updates on ng.guide will go live as soon as Nx 20 adds support for Angular 20.


🎁 Pre-order now — "Angular UI Kit"

We’re launching our first interactive course on ng.guide, where you'll build a production-grade UI library using real-world Angular practices.

  • Fully interactive lessons
  • Real components and examples
  • One-click Stackblitz integration

💸 Early-bird price: $99 (was $125) — available only before launch.

Reserve your access now and get hands-on with how Angular works at scale.


Read also