Flutter bloc pattern: Features and implementation with examples

By the title, you must have got an idea about what this article will be. As Flutter is growing day by day, developers always look for an easy way to deal with the code. So as the title, we’ll be covering Flutter bloc pattern in detail: its features, implementation with examples in Flutter.


Why use Flutter bloc pattern?

A Flutter bloc pattern makes it easy to separate the presentation layer from the business logic, making your code fast, easy to test, and reusable. As a Flutter developer, I want to:

  • know what state my application is in at any point in time
  • easily test each case to make sure my app is responding appropriately
  • record every single user interaction in my application so I can make data-driven decisions
  • work as efficiently as possible and reuse components both within may application and across apps
  • have many developers seamlessly working within a single code base, following the same patterns and conventions
  • develop fast and reactive apps

There are many architectures to choose from. Deciding which one to use can be daunting, as no architecture can ever fulfill all your needs. BLoC, which was specifically developed for Flutter, is the closest to perfection for the Flutter framework. As it’s built around three core values:

  • Simplicity
  • Testability
  • Power

BLoC is rather simple and elegant, which makes it easy to understand for both junior and experienced Flutter developers.
The ability to create complex applications out of smaller components is what makes the BLoC architecture powerful. And while these small components are discrete, it’s also easy to test any aspect of an application.

It attempts to make state changes predictable by regulating when a state change can occur and enforcing a single way to change state throughout an entire application.

Also read: Flutter first application: How to create a simple app to know the basics

How does the Flutter bloc pattern architecture work?

This simple diagram demonstrates how it works.

bloc architecture flutter
BLoC architecture is rather simple, and this is what makes it easy to test and expand

When a user clicks and interacts with the UI, they send an action or an event to the BLoC component. The main responsibility of the BLoC component is to interpret the action, handle it, and return a new or updated state to the UI component.

The BLoC component has to do all work related to the business logic (i.e. fetch data from the internet and process it). After it does this, it has to send the state to the UI component, which is responsible for handling the state component and showing it appropriately.

Main concepts

Events and actions are the inputs of the BLoC architecture. They’re commonly created in response to user interactions with an interface, such as button presses or lifecycle events like page loads. When designing an app, we need to step back and define how users will interact with it.

States are the outputs of the BLoC architecture. Moreover, they represent part of your app’s common state. UI components can be notified of states and redraw portions of themselves based on the current state.

A BLoC (Business Logic Component) converts a stream of incoming events into a stream of outgoing states. Think of a BLoC as the “brain” that receives information, processes it and provides a response.

stream is a sequence of asynchronous data. The UI and BLoC listen to this stream and respond to any changes. Check out the official Dart documentation for more information about streams.

Best way to use the BLoC architecture

There are two approaches when it comes to developing mobile apps on Flutter and, in particular, developing their architecture: you can either do everything from scratch or use a ready solution.

If you develop your Flutter app’s architecture from scratch, you’ll need to create custom code and streams. This takes time, and in the long run can lead to boilerplate or spaghetti code. This will make your application hard to maintain.

Google’s Bloc library is one of the best solutions you can use for your Flutter project’s architecture.

Adding the Google Bloc library to your project

To use the Google Bloc library, add the flutter_bloc: ^2.0.1 dependency to your pub spec.yaml file. This Flutter package helps to implement the Flutter bloc pattern in your project.

Widgets in the Flutter bloc pattern library


To use the Bloc component, you have to extend the Bloc class and override the mapEventToState and initialState methods, which are responsible for initiating the first state of the UI component.

In the mapEventToState method, you’ll receive your specified actions as an argument, handle that argument, and return it as a state. Let’s see a standard example in which our Bloc, which is responsible for incrementing or decrementing the value, depends on the input action.

enum CounterEvent { increment, decrement }
class CounterBloc extends Bloc {
@override int get initialState => 0;
@override Stream mapEventToState(CounterEvent event) async* {
switch (event) {
case CounterEvent.decrement:
yield state - 1; break; case CounterEvent.increment:
yield state + 1; break; } } }

In the example above, we receive a CounterEvent from the UI and handle it according to the event type. After that, we return the state immediately. In our case, the state is an int. In the Bloc component, we implement all the business logic we need. We also can create an abstract state and extend it to customize our responses. The same works for events.

//Customised state @immutable abstract class IncomingState {} 
class InitialIncomingState extends IncomingState {}
class HandledState extends IncomingState {
final int counter;
}@immutable abstract class IncomingEvent {}
class IncrementEvent extends IncomingEvent {
IncrementEvent(); }class DecrementEvent extends IncomingEvent {
DecrementEvent(); }


BlocBuilder is a Flutter widget that requires a Bloc and a builder function. It builds widgets in response to new states. It’s very similar to StreamBuilder, but it has a simpler API that helps to reduce the amount of boilerplate code in your app.

The builder function can potentially be called many times and should be a pure function that returns a widget in response to the state.

Note that you should specify the bloc if you want to provide one that will be scoped to a single widget and won’t be accessible via the parent BlocProvider and the current BuildContext:

bloc: blocA, // provide the local bloc instance builder: (context, state) {
// return widget here based on the state of BlocA} )

In this example, BlocA is a type of an extended Bloc class that you need to provide in the bloc argument. In the builder, you’ll receive instances of your state classes. As I mentioned above, the first state will be the state that was created in the initialState method.

Important: Don’t create an instance of the Bloc class when you create the BlocBuilder class. Because you need to close streams in the class to avoid memory leaks. The best way to do this is to create a Bloc instance in the initState method and close it using blocA.close() in the dispose method.


BlocProvider is a Flutter widget that provides a bloc to its children via BlocProvider.of(context). It’s used as a dependency injection widget so that a single instance of a bloc can be provided to multiple widgets within a subtree.
In most cases, BlocProvider should be used to build new blocs that will then be available to the rest of the subtree. In this case, since it is responsible for creating the bloc, it will automatically close it as well.

builder: (BuildContext context) => BlocA(), child: ChildA(), );

Sometimes, BlocProvider can be used to provide an existing bloc with a new portion of the widget tree. This capability of the BlocProvider is usually used when an existing bloc needs to be available for a new route. In this case, BlocProvider will not automatically close the bloc, since it didn’t create it.

Creating events in the Bloc library

If you want to do something with your data — for example, save it to the database, handle it, or send it over the internet — you need to send an event to the Bloc component. Doing so is rather simple: just call the bloc’s add method.


After you do this, your component will receive your event and handle it appropriately.

This is pretty much all you need to know to successfully use it for your Flutter app using Google’s Bloc library.

Final thoughts of Flutter bloc pattern

All in all, there are lots of ways to develop applications for Android and iOS with Flutter. Above all, Flutter bloc pattern, you can use well-known architectures such as MVC or MVVM. However, because Flutter is somewhat different from other programming languages and it’s widget-centric, Flutter bloc pattern is commonly considered the best Flutter architecture. In addition, if you have any questions, please Contact Us now.