Riverpod
Riverpod was written by Provider's own author, and its purpose is to fix four problems Provider has:
- Compile-time safety — providers are global variables, so there is no "not found in the tree" failure
- Reading without a context — state is reachable from outside the widget tree
- No type-based lookup — you can have as many providers of the same type as you like
- Composition — one provider can read another with
ref.watch, and the dependency is tracked automatically
On the widget side you use a ConsumerWidget, whose build receives an extra WidgetRef ref parameter.
You pick a provider type by the shape of the work:
- `Provider` — an unchanging value or a service such as a repository
- `StateProvider` — a simple mutable value (a filter, the selected tab)
- `FutureProvider` — a one-off async load; it yields an
AsyncValue - `StreamProvider` — a continuous stream
- `NotifierProvider` / `AsyncNotifierProvider` — complex state with business logic
AsyncValue is particularly useful: it unifies loading, data and error into one type and, via when(), forces you to handle all three — which is how the forgotten-error-state problem disappears.
Interview tip. Riverpod's strongest selling point is AsyncValue, and showing it with an example lands well: with Provider you juggle loading and error by hand through bool isLoading and String? error fields, and one of them gets forgotten; AsyncValue.when demands all three. When you say "compile-time safety", be concrete too: providers are globals, so a runtime ProviderNotFoundException is simply not possible.
📚 Sources and documentation
- flutter_riverpod packageofficialpub.dev
- Riverpod documentationriverpod.dev
The provider-type selection guide and the migration path from Provider live here.
- State management optionsofficialdocs.flutter.dev