Flutter · One codebase, native feel
Compare Provider, Riverpod and Bloc.
Short answer
Provider is lightweight dependency injection over InheritedWidget. Riverpod adds compile-safe providers, composition and caching without context. Bloc models state as explicit events and states with stream-based transitions.
All three solve access and rebuilds, but they optimize for different things. Provider depends on BuildContext and is easy to learn. Riverpod removes the context dependency for reads, supports auto-disposal and provider composition, and makes overrides straightforward in tests. Bloc exposes a unidirectional event-to-state flow that is easy to log and reason about in large features.
- Provider: small surface area, context-based lookup, good for simple apps
- Riverpod: providers are declared globally, testable with overrides, strong async support
- Bloc: explicit events and states, strong traceability, more ceremony per feature
- Bloc often pairs with repository and use-case layers; Riverpod can replace that wiring
final userProvider = FutureProvider.autoDispose<User>((ref) async {
final repository = ref.watch(userRepositoryProvider);
return repository.fetchCurrentUser();
});
class ProfileView extends ConsumerWidget {
const ProfileView({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
final user = ref.watch(userProvider);
return user.when(
data: (value) => Text(value.name),
loading: () => const CircularProgressIndicator(),
error: (error, stack) => const Text('Failed to load profile'),
);
}
}Trade-offs in practice
Provider can become hard to trace when many widgets read many models and lifecycle is implicit. Riverpod's global providers are not global mutable state, but the team still needs conventions for provider ownership. Bloc's ceremony pays off when state transitions must be auditable, but it can be heavy for a small settings screen.
Follow-ups you should expect
Interviewers use these to check whether the first answer was understanding or memorisation.
- 1How does Riverpod avoid the BuildContext dependency for reads?
- 2What problem do auto-dispose providers solve?
- 3When is Bloc's event stream worth the boilerplate?
- 4How would you test a Bloc compared with a Riverpod provider?
Say it in the interview
Provider is the simplest: it is inherited dependency injection with context lookup. Riverpod keeps providers declarative and testable without context, and gives me auto-disposal and easy overrides. Bloc makes transitions explicit through events and states, which is valuable when many people need to reason about a complex flow. I choose based on feature complexity and team familiarity, not on which one has the most features.
Use this as a model, not a script. Saying it in your own words is what makes it survive follow-up pressure.
Related questions
Reading is step one
Now say it out loud.
Understanding an answer and delivering it under pressure are different skills. Rehearse this topic in a live Flutter mock interview and get scored feedback on depth, clarity and confidence.