Comparison and justifying the choice
In an interview, the "which state management?" question is not after a library name — it wants to see your decision process. The structure of a strong answer:
1. Ask for context (team, product lifetime, share of async work, audit requirements). 2. Name the criteria. 3. Make the decision and state why you rejected the alternative. 4. Name the risk and how you mitigate it. 5. Cite the official position: the Flutter team gives no single recommendation — the choice depends on the app's complexity, the team's preferences and the problems to be solved.
| Question | Provider | Riverpod 3 | BLoC / Cubit |
|---|---|---|---|
| Learning curve | Low | Medium (a new mental model) | Medium-high (event/state discipline) |
| Async state | Hand-written flags | `AsyncValue` built in | A status enum or sealed states |
| Reading a wrong provider | A runtime error | Visible at compile time | A runtime error |
| Testing: replacing a dependency | Rebuilding the tree by hand | `overrides` — one line | `bloc_test`, `MockBloc`, `whenListen` |
| Testing the state sequence | A hand-written listener | `container.listen` | `blocTest(expect: ...)` — the most ready-made |
| Audit / event log | Hand-rolled | Observers | `BlocObserver` plus `onTransition` |
| Debounce / concurrency control | Hand-rolled | Hand-rolled (or indirectly via `select`/`autoDispose`) | `EventTransformer` plus `bloc_concurrency` |
| The official DI recommendation | Chosen by the official case study | The provider graph doubles as DI | `RepositoryProvider` (provider inside) |
A fact that stands out in an interview: flutter_bloc implements BlocProvider, MultiBlocProvider and RepositoryProvider with package:provider and re-exports its context.read/watch/select extensions. So "Provider or BLoC?" is not a question about mechanism — it is a question about discipline and convention. That answer lifts the comparison above the surface level.
Ready-made argument sets (usable verbatim in an interview):
- Why Riverpod? — Async state comes built in (
AsyncValue), dependencies are replaced in tests with a one-lineoverride, providers are checked at compile time, andautoDisposecleans memory on its own. The cost: a new mental model and codegen build time. - Why BLoC? — The docs' two points: traceability (
onTransition, state → event → state) and advanced event transformations (debounce, droppable). A discipline advantage in audited flows and large teams. The cost: boilerplate. - Why Provider? — The lowest learning curve, the DI choice of the official architecture case study, and the official example in Flutter's docs. Enough for small and medium apps. The cost: hand-written async state and runtime errors.
- Why mixed? — BLoC for the payment flow (audit), Riverpod for the rest (async). The condition: the boundary is documented and never mixed within a screen.
📚 Sources and documentation
- Flutter: state management optionsofficialdocs.flutter.dev
The source of the "no single recommendation" position — a citation for interviews.
- Why Bloc?officialbloclibrary.dev
- Riverpod: motivationofficialriverpod.dev
- Flutter architecture guideofficialdocs.flutter.dev