How to create a shopping cart app using BLoC pattern in Flutter
The BLoC pattern in Flutter is a mature way to manage state in a Flutter app. In this tutorial, we’ll be building a simple shopping cart app that uses the BLoC pattern. Here’s the final app:

Before you proceed
- I wrote the code on Flutter version 1.12.13+hotfix.9.
- I used VSCode for this tutorial, but you can use whatever you’ve been using. I’m certain you’ll follow. You can get all the code from my [GitHub repo].(https://github.com/Vicradon/shopping-cart-app)
- I don’t assume you have in-depth knowledge of Flutter. You can follow along if you are a beginner, although I assume that you’ve heard of Flutter and what it offers.
Set up
Create a new Flutter project by running the following command (ensure you choose a package name):
flutter create --org com.choose_a_package_name shopping_cart_app
You can choose to ignore the --org com.choose_a_package_name tag. Choosing a package name when creating the project ensures that you don’t have to go through the hassle of changing it in several places if you want to change it in the future.
Here’s our folder structure to guide you.
lib
│ main.dart
└───bloc
│ │ cart_items_block.dart
└───pages
│ checkout.dart
│ shop_items.dart
Clean up the main.dart file in the lib folder. Then copy and paste this block:
We haven’t imported the items list and checkout widgets yet, so we’ll get a linting error. Let’s fix that.
We still don’t have anything in those files. Let’s add the basic classes.
Create the pages
In your lib folder, create a pages folder and create two files:
shop_items.dartcheckout.dart
Paste this snippet in shop_items.dart:
And now, for checkout.dart:
Now that all the pressing errors have been fixed, let’s finish up the main.dart file. This is also a good time to run your app (if you haven’t already). Navigate to the main.dart file and click the fn and f5 keys. It runs your code automatically whenever there’s a change (essentially a debug mode), as opposed to running flutter run in the terminal.
A little note about BLoC pattern
The BLoC (Business Logic Component) pattern is implemented by having
- One or several BLoC classes which:
- contain data (or communicate with models which in turn contain data) and
- set up streams for continuous data delivery, especially when the data changes.
- These streams receive data from sinks: Sink => Stream. Sinks are kept in sync with the current data object.
- Widgets subscribe to the BLoCs using StreamBuilders. The widget becomes a child of the StreamBuilder. The StreamBuilder rebuilds the widget when the BLoC’s data changes (i.e., the stream receives new data).
In a nutshell, we deal with BLoC classes (sinks and streams) and StreamBuilders.
Building out our BLoC class
We’ll implement the BLoC for our shop and cart.
- The shop models a literal shop where you pick stuff up.
- The cart models a literal trolley you put stuff in.
Paste this block into the cart_items_bloc.dart file.
This is the basic structure of our BLoC. All our data will be stored in the allItems map. When our data is modified, we will add the modified map to the cartStreamController sink.
Now, let’s add data to our Map object. In the same file, locate the allItems map.
I manually assigned id's to the object. In a real app, you’d want to use a package like UUID.
Now, we’ll implement methods for modifying the data in the allItems map. We’ll add:
- An
addToCartmethod for adding items from the shop to the cart. - A
removeFromCartmethod for removing items from the cart, back to the shop.
Finally, we need to instantiate the bloc at the end of the file. Since we’ll be using it in multiple screens, we won’t want to instantiate twice.
Anytime we import this file, the bloc instance will be available to us.
Using our bloc in our pages
The shop_items.dart page
Navigate to the shop_items.dart page.
First, import the BLoC class.
Then, go to the ShopItemsWidget class and add the new code.
We need a ListView.builder to generate ListTiles from our array of items.
We’re done with shop_items.dart.
On to greater things comrade.
The checkout.dart page
We’ve written most of the code. All we need to do is copy code we’ve already written.
Navigate to the checkout.dart page and import the BLoC.
Then, add the new content in the Checkout class.
Finally, add the checkoutListBuilder.
So, this is all for checkout.dart page. Technically, this is all for the app.
Verify that everything works in your emulator or device. If you get an error, check the error message printed on the console and start debugging from there.

Congrats on reaching the end.
What could we improve? For starters, you can rename the bloc object (instance of the CartItemsBloc class) to something more descriptive, like cartItemsBloc. I named it bloc because this app is simple. If we were working with multiple BLoC classes, we’d have to be more descriptive in naming our variables.
I hope you’ve gotten the basics of streams and the BLoC pattern. You can reach out to me on Twitter (do follow me) if you have questions, complaints, or comments. You can also find all the code on GitHub. Thanks for coding along. ✨