Flutter State Management 2026: Riverpod vs Bloc vs Provider
Jeder Flutter-Entwickler steht früher oder später vor der Frage: Welches State Management soll ich nutzen? Nach Jahren in Production mit allen drei Lösungen gebe ich euch hier meine ehrliche Einschätzung.
TL;DR für die Ungeduldigen
Meine Empfehlung 2026: Bloc. Die strikte Architektur zahlt sich langfristig aus. Aber lest weiter, denn es kommt auf euren Use Case an.
Die Kandidaten im Überblick
Aktuelle Versionen (Stand Februar 2026)
- Riverpod
3.2.1(7.1k GitHub Stars) - Bloc
9.1.1(12.4k GitHub Stars) - Provider
6.1.5(Teil des Flutter Favorites Programms)
Alle drei sind production-ready und werden aktiv maintained.
Provider: Der Klassiker
Provider ist der offizielle Einstiegspunkt für State Management in Flutter. Es ist ein Wrapper um InheritedWidget und macht Dependency Injection einfach.
Code-Beispiel: Counter mit Provider
// 1. State definieren
class CounterNotifier extends ChangeNotifier {
int _count = 0;
int get count => _count;
void increment() {
_count++;
notifyListeners();
}
}
// 2. Provider registrieren
void main() {
runApp(
ChangeNotifierProvider(
create: (_) => CounterNotifier(),
child: const MyApp(),
),
);
}
// 3. State konsumieren
class CounterPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
final counter = context.watch<CounterNotifier>();
return Text('Count: ${counter.count}');
}
}
Vorteile von Provider
- Offiziell von Flutter empfohlen
- Einfach zu lernen
- Minimaler Boilerplate
- Perfekte Integration mit Flutter DevTools
Nachteile von Provider
- Abhängig vom Widget-Tree (
ProviderNotFoundExceptionlässt grüßen) - Schwierig bei komplexen Provider-Dependencies
- Keine Compile-Time Safety
Bloc: Der Enterprise-Standard
Bloc (Business Logic Component) folgt dem Event-State Pattern und ist bekannt für strikte Architektur und Testbarkeit.
Code-Beispiel: Counter mit Bloc
// 1. Events definieren
sealed class CounterEvent {}
class IncrementPressed extends CounterEvent {}
// 2. Bloc implementieren
class CounterBloc extends Bloc<CounterEvent, int> {
CounterBloc() : super(0) {
on<IncrementPressed>((event, emit) {
emit(state + 1);
});
}
}
// 3. UI anbinden
class CounterPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return BlocBuilder<CounterBloc, int>(
builder: (context, count) {
return Column(
children: [
Text('Count: $count'),
ElevatedButton(
onPressed: () => context.read<CounterBloc>().add(IncrementPressed()),
child: const Text('Increment'),
),
],
);
},
);
}
}
Vorteile von Bloc
- Strikte Trennung von UI und Business Logic
- Hervorragende Testbarkeit durch
bloc_test - Vorhersagbarer State durch Event-Sourcing
- Große Community (12.4k GitHub Stars)
- Dediziertes Linting mit
bloc_lint
Nachteile von Bloc
- Viel Boilerplate (Events, States, Bloc-Klassen)
- Steile Lernkurve für Einsteiger
- Kann für einfache Features overkill sein
- Cubit als Alternative ist einfacher, aber inkonsequent
Riverpod: Der moderne Ansatz
Riverpod (ein Anagramm von "Provider") wurde vom gleichen Autor entwickelt, um die Limitierungen von Provider zu überwinden. Mit Version 3.0 (September 2025) ist es zum reaktiven Caching und Data-Binding Framework geworden.
Code-Beispiel: Counter mit Riverpod
// 1. Provider definieren (global, außerhalb des Widget-Trees)
@riverpod
class Counter extends _$Counter {
@override
int build() => 0;
void increment() => state++;
}
// 2. App mit ProviderScope wrappen
void main() {
runApp(
ProviderScope(
child: const MyApp(),
),
);
}
// 3. State konsumieren
class CounterPage extends ConsumerWidget {
@override
Widget build(BuildContext context, WidgetRef ref) {
final count = ref.watch(counterProvider);
return Column(
children: [
Text('Count: $count'),
ElevatedButton(
onPressed: () => ref.read(counterProvider.notifier).increment(),
child: const Text('Increment'),
),
],
);
}
}
Async Data Handling: Riverpods Killer-Feature
@riverpod
Future<User> user(Ref ref) async {
final response = await http.get(Uri.parse('https://api.example.com/user'));
return User.fromJson(jsonDecode(response.body));
}
// In der UI: Loading, Error und Data automatisch gehandelt
class UserPage extends ConsumerWidget {
@override
Widget build(BuildContext context, WidgetRef ref) {
final userAsync = ref.watch(userProvider);
return switch (userAsync) {
AsyncData(:final value) => Text('Hello, ${value.name}'),
AsyncError(:final error) => Text('Error: $error'),
_ => const CircularProgressIndicator(),
};
}
}
Vorteile von Riverpod
- Compile-Time Safety: keine Runtime-Exceptions
- Widget-Tree unabhängig: Provider sind global
- Exzellentes Async-Handling: Loading/Error States out of the box
- Code Generation mit
riverpod_generatorreduziert Boilerplate - Auto-Dispose: Memory Management automatisch
- Reactive Caching: inspiriert von React Query
Nachteile von Riverpod
- Lernkurve für das neue mentale Modell
- Mehr Setup durch Code Generation
- Kleinere Community als Bloc (7.1k vs 12.4k Stars)
- Breaking Changes zwischen Major Versions
Wann welches Pattern nutzen?
Nutze Provider wenn:
- Du Flutter gerade lernst
- Deine App sehr einfach ist
- Du minimale Dependencies willst
- Das Team Provider bereits kennt
Nutze Bloc wenn:
- Du in einem großen Team arbeitest
- Strikte Architektur wichtig ist
- Du Event-Sourcing brauchst
- Enterprise-Umgebung mit strengen Code-Reviews
Nutze Riverpod wenn:
- Du viel mit Async-Daten arbeitest (APIs, Datenbanken)
- Du moderne Dart-Features nutzen willst
- Du Compile-Time Safety schätzt
- Du ein neues Projekt startest (2025/2026)
Was nutzen große Flutter Apps?
- BMW, eBay, Google Pay: Primär Bloc
- Viele Indie-Apps und Startups: Trend zu Riverpod
- Legacy-Projekte: Oft noch Provider
Code With Andrea's Empfehlung
Andrea Bizzotto, einer der respektiertesten Flutter-Educators, empfiehlt Riverpod für neue Projekte. Seine Flutter Architecture mit Riverpod gilt als Best Practice. Sein Guide "Flutter Riverpod 2.0: The Ultimate Guide" ist Pflichtlektüre.
Migration zwischen den Lösungen
Provider → Riverpod
Relativ einfach, da der Autor derselbe ist. Riverpod kann neben Provider existieren für schrittweise Migration.
Bloc → Riverpod
Aufwändiger, da komplett anderes Paradigma. Besser bei neuen Features starten, statt alles auf einmal zu migrieren.
Provider → Bloc
Ebenfalls aufwändig. Bloc erfordert das Umdenken in Events/States.
Meine persönliche Empfehlung
Für neue Projekte 2026: Bloc.
Warum? Die strikte Trennung von Events und States zwingt dich zu sauberem Code. Klar, es ist mehr Boilerplate, aber aus meiner Erfahrung kann ich sagen: Diese Struktur rettet dir den Arsch, wenn das Projekt wächst. Die Testbarkeit ist ungeschlagen, und mit bloc_test schreibst du Tests, die wirklich was aussagen.
Riverpod? Absolut valide, besonders wenn du viel mit Async-Daten arbeitest. Das AsyncValue-Pattern ist elegant. Aber mir fehlt die strikte Architektur. Es ist zu einfach, Spaghetti-Code zu schreiben.
Provider? Nur noch für sehr einfache Apps oder zum Lernen. Für Production würde ich heute nicht mehr damit anfangen. Wenn du gerade erst anfängst, hilft dir mein Flutter-Lernguide.
Fazit
Es gibt kein "falsches" State Management, nur das falsche für deinen Use Case. Alle drei Lösungen sind production-ready und werden von großen Apps genutzt. Wenn dein State komplexer wird, lohnt sich ein Blick auf State Machines für Flutter-UIs. Wie du Module, Dependency Injection und Lint-Regeln drumherum aufsetzt, steht in Flutter-Architektur, die nicht verrottet.
Meine Faustregel:
- Lernprojekt → Provider
- Jedes ernsthafte Projekt → Bloc
- Async-heavy Apps (viele API-Calls) → Riverpod als Alternative
Was nutzt ihr? Schreibt mir auf Twitter @robocitrus. Ich bin gespannt auf eure Erfahrungen!
Dieser Artikel wird regelmäßig aktualisiert. Letzte Aktualisierung: Februar 2026.



