Flutter · One codebase, native feel

Compare Provider, Riverpod and Bloc.

Mediumproviderriverpodblocstate managementUpdated Oct 2026
Quiz this track

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
dart
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.

Do not mix three solutions in one feature without a boundary. Choose one per layer or per feature and document the rule, otherwise rebuild behaviour becomes unpredictable.

Follow-ups you should expect

Interviewers use these to check whether the first answer was understanding or memorisation.

  1. 1How does Riverpod avoid the BuildContext dependency for reads?
  2. 2What problem do auto-dispose providers solve?
  3. 3When is Bloc's event stream worth the boilerplate?
  4. 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.