flutter
/

MultiBlocProvider: Managing Multiple Blocs in Flutter

Last Sync: Today

On this page

10
0%
5 min read
Remaining
5 minleft

Click any section to jump — progress syncs automatically

flutter

MultiBlocProvider: Managing Multiple Blocs in Flutter

As your Flutter app grows, you'll often need to provide multiple blocs to different parts of the widget tree. Nesting BlocProvider widgets works, but can lead to deeply indented code. MultiBlocProvider solves this by combining multiple providers into a single widget, improving readability and maintainability.

What is MultiBlocProvider?

MultiBlocProvider is a convenience widget that merges multiple BlocProvider widgets into one. It takes a list of providers and a single child, effectively flattening the widget tree. Internally, it nests the providers in the order they are given, but without the visual indentation.

When to Use MultiBlocProvider

  • Top-level app setup – Provide global blocs (e.g., AuthBloc, ThemeBloc) near the root.
  • Feature modules – Group all blocs needed for a feature in one place.
  • Any time you have 2+ BlocProviders – Improves readability and reduces nesting.

Basic Usage

Replace nested BlocProvider widgets with MultiBlocProvider. The order of providers matters: they are applied from top to bottom, so later providers can depend on earlier ones.

DARTRead-only
1
// Instead of this:
BlocProvider<AuthBloc>(
  create: (context) => AuthBloc(),
  child: BlocProvider<ProfileBloc>(
    create: (context) => ProfileBloc(context.read<AuthBloc>()),
    child: MyApp(),
  ),
)

// Use MultiBlocProvider:
MultiBlocProvider(
  providers: [
    BlocProvider<AuthBloc>(create: (context) => AuthBloc()),
    BlocProvider<ProfileBloc>(
      create: (context) => ProfileBloc(context.read<AuthBloc>()),
    ),
  ],
  child: MyApp(),
)

Nesting vs MultiBlocProvider

While MultiBlocProvider is cleaner, sometimes you still need explicit nesting for scoping reasons. For example, if you want a bloc to be available only inside a specific subtree, you might nest a BlocProvider inside a child of a MultiBlocProvider. The two approaches can be combined.

DARTRead-only
1
MultiBlocProvider(
  providers: [
    BlocProvider<AuthBloc>(create: (_) => AuthBloc()),
  ],
  child: SomeWidget(
    child: BlocProvider<FeatureBloc>(
      create: (_) => FeatureBloc(),
      child: FeatureScreen(),
    ),
  ),
)

Scoping with MultiBlocProvider

Each BlocProvider in the list creates its own scope. Blocs are available to all descendants of the MultiBlocProvider. If you need a bloc only in a part of the tree, place the MultiBlocProvider at the appropriate level.

DARTRead-only
1
class FeaturePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MultiBlocProvider(
      providers: [
        BlocProvider<FormBloc>(create: (_) => FormBloc()),
        BlocProvider<ValidationBloc>(create: (_) => ValidationBloc()),
      ],
      child: FormScreen(), // only these blocs are available here
    );
  }
}

Combining with Other Bloc Widgets

MultiBlocProvider works seamlessly with other bloc widgets like BlocBuilder, BlocListener, and BlocConsumer. You can also combine it with MultiRepositoryProvider if you need to provide repositories.

DARTRead-only
1
MultiBlocProvider(
  providers: [
    BlocProvider<AuthBloc>(create: (_) => AuthBloc()),
    BlocProvider<SettingsBloc>(create: (_) => SettingsBloc()),
  ],
  child: MultiRepositoryProvider(
    providers: [
      RepositoryProvider<AuthRepository>(create: (_) => AuthRepositoryImpl()),
      RepositoryProvider<SettingsRepository>(create: (_) => SettingsRepositoryImpl()),
    ],
    child: MyApp(),
  ),
)

Performance Considerations

MultiBlocProvider does not add any runtime overhead compared to nested providers – it simply reorganises the code. The create functions are called only once when the widget is inserted, so there's no performance penalty. However, be mindful of creating blocs that are never used; provide them only where needed.

Best Practices

  • Group related blocs – Keep providers together in a MultiBlocProvider at the feature or app level.
  • Maintain order – Ensure dependent blocs come after the blocs they depend on in the providers list.
  • Use for root providers – Place global blocs (auth, theme) in a MultiBlocProvider above MaterialApp.
  • Combine with MultiRepositoryProvider – Keep DI clean by grouping both blocs and repositories.
  • Avoid over-providing – Don't provide a bloc at the top if it's only needed in one branch; scope it lower.

Common Mistakes

  • ❌ Incorrect order – Placing a bloc that depends on another before it in the list will cause a ProviderNotFoundException.
  • ❌ Providing too many blocs globally – Increases memory usage and can lead to unintended state sharing.
  • ❌ Forgetting to use MultiBlocProvider for multiple providers – Leads to deeply nested code that is hard to read.
  • ❌ Creating a bloc inside build inside the provider – Ensure create is a function that returns a new instance, not an existing one.

What's Next?

Now that you can manage multiple blocs efficiently, learn how to test them and handle more advanced scenarios like dependency injection with get_it.

Next, explore Bloc testing and Dependency injection with get_it.

Test Your Knowledge

Q1
of 3

What is the primary benefit of using MultiBlocProvider over nested BlocProvider widgets?

A
Performance improvement
B
Reduced nesting and improved readability
C
Automatic bloc disposal
D
Ability to provide multiple bloc types
Q2
of 3

In a MultiBlocProvider, which statement about the order of providers is true?

A
Order doesn't matter
B
Providers are applied in reverse order
C
Later providers can depend on earlier providers
D
All providers are created simultaneously
Q3
of 3

What happens if you try to access a bloc that is provided later in the MultiBlocProvider list from an earlier provider's create function?

A
It works because all providers are created together
B
It throws a ProviderNotFoundException
C
It returns null
D
It creates the bloc automatically

Frequently Asked Questions

Is MultiBlocProvider the same as nesting BlocProvider widgets?

Yes, functionally it is identical. MultiBlocProvider is just a convenience that reduces nesting and improves readability. The order of providers is preserved, and each provider's lifecycle is independent.

Can I use MultiBlocProvider with BlocProvider.value?

Yes, you can include BlocProvider.value in the providers list. However, remember that BlocProvider.value does not automatically close the bloc, so ensure the bloc is properly managed elsewhere.

How many providers can I put in MultiBlocProvider?

There's no practical limit, but it's a good practice to keep the list manageable. If you have many providers, consider splitting them into multiple MultiBlocProvider widgets at different levels of the tree to better scope them.

Does the order of providers in MultiBlocProvider matter?

Yes. The create functions are called in the order they appear. If a later bloc depends on an earlier one (via context.read), it will work. If you reverse the order, it may fail because the dependency isn't yet available.

Previous

bloc provider

Next

bloc builder

Related Content

Need help?

Explore our comprehensive docs or start a chat with our tech experts.