Angular 21 : zoneless par défaut et Signal Forms ⚡
Angular 21 débarque le 20 novembre 2025 avec son lot de nouveautés qui simplifient le développement et améliorent les performances. Zoneless par défaut, Signal Forms expérimentaux, support de l’IA… Cette version met l’accent sur la modernisation et la performance.
⚡️ Zoneless par défaut
C’est LE grand changement d’Angular 21 : les nouvelles applications n’utilisent plus zone.js par défaut. Fini les
détections de changement mystérieuses et les stack traces incompréhensibles !
Qu’est-ce que ça change ?
Historiquement, Angular utilisait zone.js pour détecter automatiquement les changements (clic, timer, requête HTTP,
etc.). C’était pratique mais gourmand : Angular vérifiait souvent plus que nécessaire.
Avec le mode zoneless, la détection repose sur les signals et les événements du template. Résultat :
- Moins de vérifications inutiles
- Bundle plus léger (pas de
zone.js) - Stack traces plus claires
- Comportement plus prévisible
Comment l’utiliser ?
Pour les nouvelles applications, c’est automatique avec ng new. Pour migrer une app existante :
import { provideZonelessChangeDetection } from '@angular/core';
bootstrapApplication(App, {
providers: [provideZonelessChangeDetection()],
});Retirez ensuite zone.js de votre angular.json et de vos polyfills !
Ce qui fonctionne sans changement
- Les événements de template (
(click),(input), etc.) - Les signals et
computed() - Les
input()de composant HttpClientavec signals
@Component({
template: `
@if (pokemon()) {
<h2>{{ pokemon().name }} (lvl {{ level() }})</h2>
<button (click)="levelUp()">Niveau +1</button>
}
`,
})
export class PokemonCard {
pokemon = input.required<Pokemon>();
level = signal(1);
levelUp() {
this.level.update((lvl) => lvl + 1);
}
}Points d’attention
Si votre code dépend de timers ou callbacks sans signals, ajoutez markForCheck() :
constructor(private cdr: ChangeDetectorRef) {
setTimeout(() => {
this.data = newValue;
this.cdr.markForCheck(); // ← nécessaire en zoneless
}, 1000);
}Ou mieux : utilisez des signals !
📝 Signal Forms (expérimental)
Angular 21 introduit une nouvelle approche des formulaires entièrement basée sur les signals. C’est encore expérimental, mais ça promet !
Créer un formulaire
Un formulaire Signal se construit à partir d’un signal contenant les données :
import { form, required, minLength } from '@angular/forms/signals';
@Component({
selector: 'pokemon-form',
template: `
<form (submit)="save($event)">
<label>Nom</label>
<input [field]="pokemonForm.name" />
<label>Type</label>
<input [field]="pokemonForm.type" />
<button [disabled]="!pokemonForm().valid()">Enregistrer</button>
</form>
`,
})
export class PokemonFormComponent {
pokemon = signal({ name: '', type: '' });
pokemonForm = form(this.pokemon, (path) => {
required(path.name, { message: 'Le nom est requis' });
minLength(path.name, 3, { message: 'Au moins 3 caractères' });
required(path.type);
});
save(event: SubmitEvent) {
event.preventDefault();
submit(this.pokemonForm, async (form) => {
const pokemon = form().value();
return this.pokemonService.save(pokemon);
});
}
}Afficher les erreurs
Les erreurs sont exposées sous forme d’array d’objets :
@if (pokemonForm.name().touched() && !pokemonForm.name().valid()) {
<div>
@for (error of pokemonForm.name().errors(); track error.kind) {
<p>{{ error.message }}</p>
}
</div>
}Validateurs disponibles
required(),minLength(),maxLength()min(),max(),email(),pattern()validateStandardSchema()pour Zod, Valibot, etc.
Soumission asynchrone
La fonction submit() gère automatiquement la validation et l’état submitting :
submit(this.pokemonForm, async (form) => {
const { name, type } = form().value();
return this.http.post('/api/pokemons', { name, type });
});Pendant la soumission, pokemonForm().submitting est true et peut être utilisé pour un spinner.
🤖 Angular MCP Server pour l’IA
Angular 21 lance le Angular MCP Server, un outil pour améliorer les workflows avec l’IA. MCP (Model Context Protocol) permet aux LLM d’accéder à votre contexte de projet Angular.
À quoi ça sert ?
- Génération de code contextualisée
- Suggestions basées sur votre architecture
- Assistance pour les migrations
- Génération de tests cohérents
C’est encore en phase d’adoption, mais c’est un premier pas vers des outils IA plus intelligents pour Angular !
📦 HttpClient par défaut
HttpClient est maintenant fourni par défaut dans les nouvelles applications. Plus besoin d’importer
provideHttpClient() manuellement !
// Avant Angular 21
bootstrapApplication(App, {
providers: [provideHttpClient()],
});
// Avec Angular 21
bootstrapApplication(App, {
providers: [
// HttpClient est déjà disponible !
],
});🔧 Améliorations du styling avec NgStyle
NgStyle fonctionne désormais parfaitement avec la nouvelle syntaxe de contrôle de flux (@if, @for). Plus de
comportements étranges !
@Component({
template: `
@for (status of statuses; track status) {
<p [ngStyle]="{ color: status === 'Capturé' ? 'green' : 'red' }">
{{ status }}
</p>
}
`,
})
export class StatusList {
statuses = ['Capturé', 'En liberté', 'Évadé'];
}Combiné avec les signals, c’est encore plus puissant :
theme = signal('clair');
toggleTheme() {
this.theme.update((t) => (t === 'clair' ? 'sombre' : 'clair'));
}<div [ngStyle]="{ backgroundColor: theme() === 'sombre' ? '#000' : '#fff' }">Contenu avec thème dynamique</div>🚀 Ce qui reste à surveiller
Angular 21 prolonge l’ère des signaux :
- Les Signal Forms sont expérimentaux et l’API peut changer
- Le mode zoneless est stable mais nécessite des ajustements sur les projets existants