La question du state management revient dans tous les projets Flutter un peu sérieux. Et les débats peuvent être vifs dans la communauté. Voici notre position après plusieurs applications Flutter en production pour des PME.
En bref. Le state management Flutter structure durablement un projet métier de plus de 10 écrans. Trois options : Provider (simple, limité à petite échelle), Bloc (rigoureux, verbeux), Riverpod (notre choix par défaut sur les applications mobiles PME). L'insight clé : le meilleur state management est celui que votre équipe maîtrisera encore dans 2 ans. Cet article compare les trois approches avec retours d'expérience production et exemples de code sur des cas métier concrets.
Pourquoi le state management compte vraiment
Sur une app simple de 3-4 écrans, n'importe quelle approche fonctionne. Mais sur une application métier avec 20+ écrans, des données partagées entre modules, des appels API multiples, et une synchronisation offline/online — un mauvais choix de state management vous fera souffrir. C'est un point structurant sur chaque projet d'application mobile sur mesure qu'on mène.
Les symptômes d'un state management mal géré : bugs difficiles à reproduire, UI qui ne se met pas à jour correctement, performance dégradée sur les listes, et code impossible à faire évoluer.
Les 3 options principales
Provider
Provider est le state management "officiel" recommandé par l'équipe Flutter pour les débutants. Simple à apprendre, bien documenté, suffisant pour des apps modestes.
On l'utilise quand : prototypage rapide, apps simples, équipes qui débutent avec Flutter.
Ses limites : dès que l'app grandit, Provider devient verbeux et difficile à tester. La gestion des dépendances entre providers peut devenir chaotique.
Bloc (Business Logic Component)
Bloc impose une architecture stricte basée sur les événements et les états. Chaque interaction utilisateur est un événement, chaque état de l'UI est explicitement modélisé.
On l'utilise quand : projets d'équipe avec plusieurs développeurs, apps avec des flux complexes, quand la testabilité est une priorité.
Ses atouts : code très prévisible, excellente séparation des responsabilités, facilité de test unitaire.
Ses limites : verbeux. Il faut créer une classe Event, une classe State, et un Bloc pour chaque fonctionnalité. Sur une app de 30 modules, c'est beaucoup de fichiers.
Riverpod
Riverpod est la solution qu'on utilise sur nos projets depuis 2 ans. C'est une réécriture de Provider par le même auteur, qui corrige ses limitations structurelles.
Ses atouts pour les projets métier :
// Exemple : provider pour les interventions terrain
final interventionsProvider = FutureProvider.autoDispose<List<Intervention>>((ref) async {
final repo = ref.watch(interventionRepositoryProvider);
return repo.getAll();
});
// Utilisation dans un widget
final interventions = ref.watch(interventionsProvider);
return interventions.when(
data: (list) => InterventionList(items: list),
loading: () => const CircularProgressIndicator(),
error: (e, _) => ErrorWidget(error: e),
);
La gestion automatique du cycle de vie (autoDispose), la composition de providers, et l'intégration native avec AsyncValue rendent Riverpod très adapté aux apps qui font beaucoup d'appels API.
Code generation avec Riverpod 2.x :
@riverpod
Future<List<Intervention>> interventions(InterventionsRef ref) async {
final repo = ref.watch(interventionRepositoryProvider);
return repo.getAll();
}
La génération de code élimine le boilerplate et réduit les erreurs.
Notre stack recommandée pour une app métier Flutter
Pour une application métier Flutter en production, on utilise :
- Riverpod pour le state management global
- GoRouter pour la navigation
- Dio pour les appels HTTP
- Drift (SQLite) pour le stockage local et le mode offline
- Freezed pour les modèles de données immutables
// Exemple de modèle avec Freezed
@freezed
class Intervention with _$Intervention {
const factory Intervention({
required String id,
required String clientId,
required DateTime date,
required InterventionStatus status,
String? notes,
}) = _Intervention;
factory Intervention.fromJson(Map<String, dynamic> json) =>
_$InterventionFromJson(json);
}
Le vrai critère de choix
Au-delà des préférences techniques, le meilleur state management est celui que votre équipe maîtrise et que vous pourrez maintenir dans 2 ans. Si vous travaillez seul et connaissez bien Bloc — restez sur Bloc. Si vous démarrez un nouveau projet d'équipe — investissez dans Riverpod.
Ce qui compte en production : la prévisibilité du comportement, la facilité de debug, et la capacité à faire évoluer l'app sans tout casser. C'est exactement le type de choix qu'on pose dès la phase de cadrage via notre méthodologie d'étude de projet.