Nouveautés 2024 - 2026
Ce qui a changé de Flutter 3.22 à Flutter 3.47, et de Dart 3.4 à Dart 3.13. Un examinateur repère vite un candidat dont les connaissances datent : une question sur Impeller, sur les dot shorthands ou sur Swift Package Manager suffit.
Objectifs
- Situer chaque version de 2024 à 2026 et citer sa nouveauté principale.
- Écrire du Dart avec la syntaxe actuelle : dot shorthands, null-aware elements, primary constructors.
- Connaître les changements de build qui cassent les projets : Impeller, AGP 9, Swift Package Manager, UIScene, pages de 16 KB.
- Répondre à « Quelles nouveautés récentes avez-vous utilisées ? » avec des exemples précis.
Le rythme des versions
Flutter publie quatre versions stables par an, en février, mai, août et novembre. Depuis 2026, les dates de coupure de branche sont publiques. Chaque version de Flutter embarque une version de Dart. Les numéros de Flutter avancent de 3 en 3 (3.41, 3.44, 3.47) parce que les versions intermédiaires sont des versions beta.
| Flutter | Date | Dart | Ce qu'il faut en retenir |
|---|---|---|---|
| 3.22 | mai 2024 | 3.4 | WebAssembly stable pour le web, Impeller sur Android en préversion (Vulkan) |
| 3.24 | août 2024 | 3.5 | Flutter GPU en préversion, premiers pas de Swift Package Manager, CarouselView |
| 3.27 | déc. 2024 | 3.6 | Impeller par défaut sur Android (API 29+ avec Vulkan), spacing sur Row et Column, nouvelle API Color, pub workspaces, séparateurs de chiffres |
| 3.29 | fév. 2025 | 3.7 | Impeller sur 100 % des appareils Android (repli OpenGLES), code Dart sur le thread principal de la plateforme, nouveau formateur, variables wildcard _ |
| 3.32 | mai 2025 | 3.8 | Hot reload web expérimental, squircles Cupertino, stylet sur Android, null-aware elements |
| 3.35 | août 2025 | 3.9 | Hot reload web par défaut, Widget Previews expérimental, serveur MCP Dart et Flutter, annonce du découplage de Material |
| 3.38 | nov. 2025 | 3.10 | Dot shorthands, build hooks stables, support iOS 26 et Xcode 26, chemin de migration UIScene |
| 3.41 | fév. 2026 | 3.11 | UIScene par défaut, assets par plateforme, Navigator.popUntilWithResult |
| 3.44 | mai 2026 | 3.12 | Swift Package Manager par défaut, Skia retiré sur Android 10+, AGP 9 avec Kotlin intégré, Material et Cupertino gelés, GenUI et Genkit Dart |
| 3.47 | août 2026 | 3.13 | Primary constructors, packages material_ui et cupertino_ui 1.0, Impeller sur desktop, Widget Previews stable, iOS 15 minimum |
| 3.50 | nov. 2026 (prévue) | 3.14 (attendue) | Dépréciation formelle de Material et Cupertino dans le SDK |
« Je suis sur la 3.47. Les changements qui m'ont le plus touché ces deux dernières années sont Impeller, qui a réglé le jank de compilation des shaders, les dot shorthands et les primary constructors côté langage, et côté build le passage à Swift Package Manager et au lifecycle UIScene sur iOS. Je lis les notes de version à chaque stable, tous les trois mois. »
Adaptez la première phrase à la version que vous utilisez vraiment. Un examinateur peut demander ce que vous avez migré et comment.
Rendu : la fin de Skia sur mobile
Impeller est le moteur de rendu qui remplace Skia. Le problème qu'il règle : Skia compilait les shaders (petits programmes exécutés par le GPU) au moment où ils étaient utilisés pour la première fois. La première animation d'un écran saccadait, c'est le fameux shader compilation jank. Impeller précompile un jeu de shaders fixe au build. Le premier affichage est donc aussi fluide que les suivants.
- iOS : Impeller est le moteur par défaut depuis la 3.10 (2023), et Skia n'y est plus disponible aujourd'hui.
- Android : par défaut depuis la 3.27 sur les appareils Vulkan, sur tous les appareils depuis la 3.29 grâce au repli OpenGLES. En 3.44, Skia est retiré sur Android 10 et plus.
- Desktop : par défaut sur macOS, Windows et Linux depuis la 3.47. Un retour temporaire à Skia reste possible, il sera retiré.
« Comment éliminez-vous le jank de première animation ? » La réponse de 2021 était de capturer les shaders avec --cache-sksl (SkSL warm-up). Elle est obsolète : avec Impeller, il n'y a plus de compilation de shaders à l'exécution, et cette option ne sert plus. Si vous la citez, dites qu'elle appartient à l'époque de Skia.
Autre changement de fond, en 3.29 : sur Android et iOS, le code Dart tourne désormais sur le thread principal de la plateforme, au lieu d'un thread UI séparé (merged threads). Conséquence pratique : les appels synchrones vers le code natif deviennent possibles via FFI. Linux a suivi en 3.41.
Dart : ce qui change dans votre code
C'est la partie qui se voit en live coding. Si vous écrivez encore Color.withOpacity ou MainAxisAlignment.center en entier, ce n'est pas faux, mais cela date votre code.
Séparateurs de chiffres (Dart 3.6)
const plafondJournalier = 50_000_00; // 50 000 MAD en centimes
const timeout = Duration(milliseconds: 30_000);
Variables wildcard (Dart 3.7)
_ n'est plus un nom de variable : c'est un emplacement ignoré. On peut l'utiliser plusieurs fois dans la même signature.
// Avant : _, __, ___ pour ignorer plusieurs paramètres
itemBuilder: (_, _) => const Divider(),
// Dans un pattern
final (montant, _) = calculerFrais(transaction);
Null-aware elements (Dart 3.8)
String? note = transaction.note;
// Avant
final lignes = [transaction.counterparty, if (note != null) note];
// Maintenant : l'élément n'est ajouté que s'il est non nul
final lignes = [transaction.counterparty, ?note];
// Aussi dans les maps, sur la clé ou la valeur
final query = {'limit': 20, 'cursor': ?cursor};
Dot shorthands (Dart 3.10)
Quand le type attendu est connu, on peut omettre le nom du type devant une valeur d'enum, un constructeur ou un membre statique. C'est la nouveauté la plus visible dans du code Flutter.
Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(padding: EdgeInsets.all(16), child: Text('Solde')),
],
)
Column(
mainAxisAlignment: .center,
crossAxisAlignment: .start,
children: [
Padding(padding: .all(16), child: Text('Solde')),
],
)
// Fonctionne aussi dans un switch et pour les constructeurs
TransactionStatus status = .pending;
switch (status) {
case .pending: afficherSablier();
case .completed || .failed: masquerSablier();
}
La règle : le shorthand se résout sur le type de contexte. Sans type de contexte, il ne compile pas. final a = .center; est une erreur, car rien n'indique de quel type il s'agit.
Primary constructors (Dart 3.13)
Le constructeur principal se déclare dans l'en-tête de la classe. Un paramètre marqué final ou var déclare aussi le champ.
class Beneficiary {
final String id;
final String name;
final String phone;
const Beneficiary({required this.id, required this.name, required this.phone});
}
class const Beneficiary({
required final String id,
required final String name,
required final String phone,
});
// Validation dans un bloc this (impossible sur un constructeur const)
class Money(final int cents) {
this : assert(cents >= 0);
}
// Héritage avec super parameters
class BusinessAccount(super.id, super.owner, final String ice) extends Account;
Dans le corps d'une classe, les constructeurs peuvent maintenant s'écrire sans répéter le nom :
class Point {
final int x;
final int y;
new(this.x, this.y);
new origin() : x = 0, y = 0;
factory clone(Point other) => Point(other.x, other.y);
}
Les mots-clés final et var sont désormais réservés aux paramètres déclarants. void f(final int x) est une erreur dès que le package passe en langage 3.13. Pour interdire la réaffectation d'un paramètre, utilisez le lint parameter_assignments.
Les macros, abandonnées
Les macros statiques, annoncées en 2024 pour remplacer build_runner, ont été abandonnées en janvier 2025. L'équipe Dart a jugé leur coût sur les performances de l'analyseur et du compilateur trop élevé. À la place : un build_runner plus rapide (deux fois ou plus dans certains cas en 2025) et les augmentations, prévues en 2026, qui faciliteront le code généré. freezed, json_serializable et riverpod_generator restent donc basés sur build_runner.
« Les macros devaient supprimer la génération de code, mais elles ont été abandonnées début 2025 pour des raisons de performance de l'analyseur. Je continue donc avec build_runner pour freezed et Riverpod, et les primary constructors de Dart 3.13 réduisent déjà une partie du code répétitif que je confiais à la génération. »
Framework : les API qui ont changé
La nouvelle API Color (3.27)
Flutter gère maintenant les espaces de couleurs étendus (Display P3). Les composantes sont des double entre 0 et 1. withOpacity est déprécié.
color.withOpacity(0.5)
color.red // int 0-255
color.withValues(alpha: 0.5)
color.r // double 0.0-1.0
spacing sur Row et Column (3.27)
Column(
spacing: 12, // remplace les SizedBox(height: 12) intercalés
children: [SoldeCard(), ActionsRapides(), DernieresTransactions()],
)
Material et Cupertino deviennent des packages
C'est le changement structurel de 2026. Material et Cupertino sortent du SDK pour évoluer à leur propre rythme, sans attendre une version de Flutter.
- 3.44 : les deux librairies sont gelées dans le framework.
- 3.47 :
material_uietcupertino_ui1.0 sur pub.dev, en opt-in. Le SDK garde les anciennes librairies.flutter_localizationsest dégroupé :GlobalMaterialLocalizations.delegatesregroupe les délégués Material, Cupertino et Widgets. - 3.50 (novembre 2026) : dépréciation formelle des librairies du SDK.
dart fix --apply --code=migrate_design_widgets
# si l'outil échoue sur pubspec.yaml :
flutter pub add material_ui cupertino_ui
dart fix --apply
Pendant la transition, MaterialUiCompatibilityBridge permet d'adopter les nouveaux packages alors que certaines dépendances importent encore package:flutter/material.dart.
Autres ajouts utiles
CarouselView(3.24), avecCarouselView.builderen 3.41 et le défilement infini en 3.44.RepeatingAnimationBuilder(3.41) pour les animations continues déclaratives.Navigator.popUntilWithResult(3.41) : dépiler plusieurs routes et renvoyer un résultat en un appel.ReorderableListView.onReorderdéprécié au profit deonReorderItem(3.44).- Matchers de test d'accessibilité
isSemanticsetisAccessibilityAnnouncement(3.41). - Squircles Cupertino (
RSuperellipse) en 3.32, pour des coins fidèles au style iOS.
Builds : ce qui casse les projets
Ce sont les changements qui font perdre une journée quand on reprend un projet resté un an sans mise à jour. En mission, c'est souvent le premier travail demandé.
Android
| Changement | Depuis | Ce qu'il faut faire |
|---|---|---|
| AGP 9 avec Kotlin intégré | 3.44 | Retirer l'application séparée du Kotlin Gradle Plugin (KGP), sinon le build échoue. Guides de migration distincts pour les apps et les plugins. |
| Matrice de versions | 3.47 | Java 17, AGP 9.1, Gradle 9.3, compileSdk et targetSdk 36, minSdk 24. Utiliser flutter.compileSdkVersion et équivalents. |
| Kotlin DSL | 3.41 | Les nouveaux projets utilisent build.gradle.kts. Savoir lire les deux syntaxes. |
| Pages mémoire de 16 KB | Google Play, nov. 2025 | Exigé pour les apps ciblant Android 15+. Échéance initiale le 1er novembre 2025, prolongations accordées ensuite ; la documentation Android annonce le blocage des mises à jour non conformes au 1er février 2027. Mettre à jour Flutter et les plugins natifs, vérifier dans l'App Bundle Explorer de la Play Console. |
| Edge-to-edge | Android 15 (targetSdk 35) | L'app dessine sous les barres système. Gérer SafeArea et MediaQuery.paddingOf. |
| Hybrid Composition++ | 3.44, opt-in | Nouveau rendu des platform views (cartes, WebView). --enable-hcpp pour tester. Deviendra le défaut. |
iOS
| Changement | Depuis | Ce qu'il faut faire |
|---|---|---|
| Swift Package Manager par défaut | 3.44 | La CLI migre seule, avec repli sur CocoaPods pour les plugins non migrés. CocoaPods est en maintenance et sera retiré. |
| Lifecycle UIScene | par défaut en 3.41 | Obligatoire avec le SDK iOS 27 : une app compilée avec Xcode 27 sans UIScene ne démarre pas. Migration manuelle si l'AppDelegate est personnalisé. |
| iOS 15 minimum | 3.47 | Relever la cible de déploiement. macOS 12 minimum. |
| Privacy manifests | Apple, mai 2024 | Fichier PrivacyInfo.xcprivacy exigé pour l'app et les SDK tiers listés par Apple. |
| Macs Intel | 3.47 | Avertissements à la compilation sur un Mac Intel, fin de support annoncée. |
« Vous reprenez une app Flutter 3.16 à mettre à jour. Comment procédez-vous ? » La mauvaise réponse : flutter upgrade puis corriger les erreurs. La bonne : lire les pages « breaking changes » des versions intermédiaires, monter par paliers sur une branche dédiée, lancer dart fix --apply à chaque palier, mettre à jour les plugins natifs en priorité, vérifier les builds Android et iOS en release, puis passer les tests et une recette manuelle des parcours critiques.
Web
WebAssembly est stable depuis la 3.22 (flutter build web --wasm) et doit devenir le défaut. Il exige package:web et dart:js_interop à la place de dart:html et package:js. Le hot reload web est disponible par défaut depuis la 3.35.
Outillage
- Widget Previews : afficher un widget isolé dans l'IDE sans lancer l'app, avec l'annotation
@Preview. Expérimental en 3.35, stable en 3.47. - Pub workspaces (Dart 3.6) : gestion native des monorepos, une seule résolution de dépendances pour plusieurs packages. Melos s'appuie maintenant dessus.
- Nouveau formateur (Dart 3.7) : style « tall », virgules finales gérées automatiquement. Le format dépend de la version de langage du package.
- DevTools compilé en WebAssembly depuis 2026, plus rapide sur les gros projets.
- Build hooks stables (Dart 3.10) : compiler et embarquer du code natif depuis un package Dart, sans plugin Flutter.
- Serveur MCP Dart et Flutter (3.35, stable fin 2025) : expose l'analyseur, le hot reload et la recherche pub.dev aux assistants de code. Voir le chapitre 15.
Écosystème : les packages qui ont bougé
| Package | Ce qui a changé |
|---|---|
| Riverpod 3 | Stable. Ref unique, retry automatique, pause des providers non visibles, Ref.mounted, ProviderContainer.test. StateNotifier, StateProvider et ChangeNotifierProvider passent dans legacy.dart. Mutations et persistance hors ligne en expérimental. Voir les chapitres 06 et 07. |
| freezed 3 et suivantes | Depuis la 3 (2025), les classes doivent être déclarées abstract ou sealed. Le pattern matching de Dart 3 (switch exhaustif) devient la façon recommandée de traiter les unions, à la place de when et map. Vérifiez dans le changelog quelles méthodes sont encore générées dans la version que vous utilisez. |
| Hive, Isar | Maintenance incertaine, forks communautaires (par exemple hive_ce). Pour une nouvelle app avec des données relationnelles, drift est le choix le plus sûr. Voir le chapitre 11. |
| shared_preferences | Nouvelles API SharedPreferencesAsync et SharedPreferencesWithCache. L'ancienne API reste disponible. |
| go_router | Maintenu par l'équipe Flutter, recommandé par la documentation officielle. |
Ce tableau est daté d'octobre 2026. Les packages bougent plus vite que Flutter. Ouvrez le changelog sur pub.dev des cinq packages que vous citerez en entretien.
Flutter et l'IA
La feuille de route 2026 de Flutter met l'IA au centre. Les éléments à connaître de nom, détaillés au chapitre 15 :
- GenUI SDK (package
genui) et le protocole A2UI : des interfaces générées selon l'intention de l'utilisateur. Version 0.10 en 3.47. - Flutter AI Toolkit : widgets de chat prêts à l'emploi, version 1.0 en 2025.
- Genkit Dart : framework pour construire des fonctionnalités d'IA en Dart. Annoncé en préversion en mai 2026, le package
genkitest depuis passé en 1.0 ; les agents et les flux bidirectionnels restent expérimentaux. - IA sur l'appareil : le package
flutter_gemma, cité à Google I/O 2026, a été renomméflutter_edge_ai, avec LiteRT-LM comme moteur recommandé. - Hot reload piloté par un agent via le serveur MCP (3.44), et des Agent Skills officielles pour Dart et Flutter.
Ce qui arrive
La feuille de route publiée en février 2026 annonce, sans date précise :
- les augmentations en Dart, pour simplifier le code généré ;
- WebAssembly par défaut pour les builds web ;
- la fin du retrait de Skia sur Android et le multi-fenêtre desktop, avec Canonical comme mainteneur principal du desktop ;
- des Dart Cloud Functions for Firebase, avec des démarrages à froid d'environ 10 ms ;
- l'étude d'un bytecode interprété pour charger des parties d'app à la demande (piste, pas un engagement).
Flutter 3.50 est attendue en novembre 2026. Relisez ce chapitre à sa sortie.
Questions d'entretien
Quelles nouveautés récentes de Flutter avez-vous utilisées ?
Citez trois éléments que vous avez réellement utilisés, un par catégorie : langage (dot shorthands, null-aware elements, patterns), framework (spacing, nouvelle API Color) et build (SwiftPM, UIScene, AGP 9). Pour chacun, une phrase sur ce que cela a changé dans le projet. Ne citez pas une nouveauté que vous n'avez que lue : la question suivante sera « comment l'avez-vous migrée ? ».
Qu'est-ce qu'Impeller et pourquoi a-t-il remplacé Skia ?
C'est le moteur de rendu de Flutter. Skia compilait les shaders à leur première utilisation, ce qui provoquait des saccades à la première animation. Impeller précompile un ensemble fixe de shaders au build, et il est conçu pour les API graphiques modernes (Metal, Vulkan). Il est le seul moteur sur iOS, le moteur par défaut sur Android depuis la 3.27, et sur desktop depuis la 3.47.
Que sont les dot shorthands ? Quand ne fonctionnent-ils pas ?
Depuis Dart 3.10, on peut écrire .center au lieu de MainAxisAlignment.center quand le type attendu est connu par le contexte. Cela marche pour les valeurs d'enum, les constructeurs (.all(16)) et les membres statiques. Sans type de contexte, par exemple final a = .center;, le compilateur ne peut pas résoudre et refuse.
Pourquoi les macros Dart ont-elles été abandonnées ?
Elles devaient remplacer build_runner, mais leur coût sur les performances de l'analyseur et de la compilation incrémentale, donc sur le hot reload et l'expérience dans l'IDE, était trop élevé. L'équipe a arrêté le projet en janvier 2025. La génération de code passe toujours par build_runner, accéléré, et les augmentations sont prévues pour 2026.
Que change le découplage de Material et Cupertino ?
Les deux librairies deviennent les packages material_ui et cupertino_ui, qui peuvent évoluer sans attendre une version de Flutter. En 3.47 c'est opt-in, avec une commande dart fix pour migrer les imports. La dépréciation formelle dans le SDK est prévue en novembre 2026. Pour un projet, il faut surveiller que les dépendances suivent, d'où le pont de compatibilité fourni.
Quel est l'impact de UIScene sur une app Flutter iOS ?
Apple impose le lifecycle basé sur les scènes. Avec le SDK iOS 27, une app qui ne l'adopte pas ne démarre plus. Flutter l'active par défaut depuis la 3.41 et migre automatiquement les projets dont l'AppDelegate n'est pas personnalisé. Si l'app a du code natif dans l'AppDelegate (notifications, deep links, SDK tiers), il faut migrer à la main vers UISceneDelegate en suivant le guide officiel, et vérifier les plugins.
Swift Package Manager ou CocoaPods ?
Swift Package Manager est le gestionnaire par défaut depuis Flutter 3.44, et CocoaPods est en maintenance. La CLI migre les projets et retombe sur CocoaPods pour les plugins qui ne supportent pas encore SwiftPM. Il faut donc vérifier les plugins natifs utilisés, en priorité les SDK de paiement, d'analytics ou de sécurité, qui sont souvent les derniers à migrer.
Comment vous tenez-vous à jour ?
Réponse concrète : les notes de version et la page « breaking changes » à chaque stable, le blog Flutter, les changelogs des packages critiques avant chaque montée de version, et une branche de test pour chaque nouvelle stable sur un projet réel. Évitez « je suis des chaînes YouTube » comme source principale.
Vous devez mettre à jour une app restée sur Flutter 3.16. Par quoi commencez-vous ?
Inventaire d'abord : version de Flutter, plugins natifs, versions Gradle, AGP et cible iOS. Puis montée par paliers sur une branche, avec dart fix --apply et la lecture des breaking changes à chaque étape. Points durs à anticiper : AGP 9 et Kotlin intégré, SwiftPM, UIScene, minSdk 24 et iOS 15, la nouvelle API Color, et freezed 3 ou plus si le projet l'utilise. Finir par des builds release sur les deux plateformes et une recette des parcours critiques.
Exercices
Réécrivez ce widget avec la syntaxe actuelle : dot shorthands, spacing, withValues, null-aware elements, et un primary constructor.
class TransactionTile extends StatelessWidget {
final String title;
final String? note;
final Color color;
const TransactionTile({super.key, required this.title, this.note, required this.color});
@override
Widget build(BuildContext context) {
return Padding(
padding: EdgeInsets.symmetric(horizontal: 16, vertical: 8),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(title, style: TextStyle(fontWeight: FontWeight.w600)),
SizedBox(height: 4),
if (note != null) Text(note!),
SizedBox(height: 4),
Container(height: 2, color: color.withOpacity(0.3)),
],
),
);
}
}
Critères : plus aucun nom de type redondant, plus de SizedBox d'espacement, plus d'opérateur !, et le code compile sur Dart 3.13.
Prenez un de vos anciens projets Flutter, sur une copie. Montez-le à la dernière stable. Notez chaque erreur rencontrée et sa cause : Gradle, AGP, Kotlin, CocoaPods ou SwiftPM, API dépréciées, plugins. Vous aurez une vraie histoire de migration à raconter en entretien, avec des détails que seul quelqu'un qui l'a fait connaît.
Répondez à voix haute, en 90 secondes chacune, à « Quelles nouveautés récentes avez-vous utilisées ? » et « Qu'est-ce qu'Impeller ? ». Enregistrez-vous. Réécoutez en vérifiant que chaque affirmation est exacte et datée.
Quiz
12 questions. Refaites-le juste avant un entretien.
Pour aller plus loin
- Notes de version Flutter
- Breaking changes Flutter, par version
- Changelog Dart
- Évolution du langage Dart
- Primary constructors
- Impeller
- Blog Flutter : les articles « What's new in Flutter » de chaque version et la feuille de route 2026