Flutter State Management with Momentum

Donald Chinhuru
7 min readApr 1, 2021


Momentum is a plugin that provides MVC pattern for flutter.

source: https://www.xamantra.dev/momentum/#/


Before we go in deep with the intro, I assume you are already familiar with flutter. I’m sure there are many state management plugins in flutter and this is no different, its certainly wasn’t made yesterday but it’s been around for a while now. I’m going to share my experience with it and i hope you will consider it and give it a try

What is Momentum

From the official docs, momentum is a MVC pattern for flutter and it sure does lives up to its promise. It comes equipped with great features out of the box and is made purely in Flutter with no other third party dependencies and is actively maintained.


  • State Management
  • Dependency Injection
  • Service Locator
  • Persistence State
  • Routing
  • Event System
  • Testing

This is going to be a series, to try to walk through some of the features listed above but not all of them. We will be building a Food App and the end goal will be like this


Add the momentum plugin to your pubspec.yaml file

MVC (Model View Controller)

momentum MVC

What is MVC

The Model-View-Controller (MVC) framework is an architectural pattern that separates an application into three main logical components Model, View, and Controller.

Here is a diagram describing the flow between state (model), widget (view) and the logic (controller).

Both MomentumController and MomentumModel are abstract classes that needs to be implemented. A pair of model and controller is called a component. MomentumBuilder is simply a widget. This is used to listen to controllers for rebuilds and accessing models to display their values.

This is all the logic behind Momentum plugin and that’s all you will be doing in your flutter project.

State Management

How do you manage state with Momentum?

Quite easy, just call model.update(..). But what is model.update(..)? If you have guessed, that’s the M for Model. The model and controller pair are called the components and will use this term throughout the series to refer to this couple.

The components have very short boilerplate codes. The controller is the logic and the Model is the state. A component is not tied to a single widget only, you can use a component in multiple pages/widgets across the app.

Example Model

This is an example model coupled together with its Controller, it sure looks like a long boilerplate code but the advantage is the reusability that you will notice later in this series. So what’s happening here? We defined our final properties, which is the state that we will want to manipulate in Controller and also access in the View of this component. This is all about your Model, you define your properties here and you are done, that’s all the Model does, you now have your model properly set. Remember the model.update(...) i mentioned, that’s the update(...) override method there, it is required to be implemented and is similar to copyWith function. If i need to change the name property in the controller or view i simply call model.update(name: 'Donny', contact: '0778xxxxxx') and the View will update automatically

There is only one way to update or rebuild widgets. That is using model.update(…) .

model.update(…) is like setState(…) but immutable and called inside logic class not inside the widgets. It’s not just for rebuilding widgets but also syncing values when something changes in the UI like user inputs.

Check out the momentum vscode extension that makes it easy to create Momentum component

Example Controller

The init() method is the initial state that is called when the app starts. The logic of the app resides in this controller, you write all functions here and its where you call that model.update(..). Properties defined in the Model can be accessed using model.propertyName for example, to grab the name, model.name.

Models are immutable so you can’t do model.name = 'Flutter'; to update the state.

You can do anything inside controllers like calling and awaiting an Api request while showing a loader on the UI etc.

Example View (Widget)

To be able to have the UI for the components to complete our trio, i will show a simple view example. This is where MomentumBuilder comes into play. Imagine in your stateless widget build method.

This is pretty straight forward, the widget that depends on the state is wrapped with the MomentumBuilder and it will react to it whenever model.update() is called. The good thing about this approach is that you can include as many controllers as you want that you want this View to access, you will see a real world example as we do the Food App so stay tuned. Note that controllers are passed as instance not like this UserController() but UserController.

Dependency Injection & service locator

Yes momentum has this out of the box and its straight forward. With momentum you can easily access almost everything, yes!. It has 3 approaches to DI.

  • Access a controller inside another controller

This is straight forward and you call controller<T>() method to access the other controller. Once you grab that, you can call any method or even the model of that controller

  • Access a controller inside the View (Widget)

Pretty straight forward again, simply call Momentum.controller<T>(context). Remember the Example View section in the FloatingActionButton? we used DI to access the controller.

  • Access inside MomentumBuilder

I think you have noticed, in the View example we only passed the Controller and we just grabbed the Model with snapshot<UserModel>(); but how do i have access to that model's controller? Quite easy too, we would have done it like this var userController = userModel.controller; and thats it :)

Ok enough with controllers, how about Services? Sometimes in my projects i like to structure services on their own for scalability, reusability and just good clean code. All my api requests i put them in one service class say ApiService and maybe all dialog services i also add them to my DialogService class for example.

To define a service class that Momentum will be able to pick, extend the MomentumService abstract class

Nothing fancy here, just a class that house all your api request, that extends momentum class.

Service locator

So how do we grab those services? Lets see the power of extending our services with MomentumService

  • Access a service inside a controller

Just use the service<T>(). Isn't that cool, the name on its own is straight forward, thats the good thing about Momentum, the name speaks for itself

  • Access service inside the View (Widget)

Just like controllers, you call Momentum.service<T>() where ever you want to locate your service

Event System

Let me wrap up with Momentum Event system. I found this really handy, so what are they?

This is handy for showing dialogs, snackbars, notifications etc. So imagine in our controllers, we call our isLoggedIn() from our service, then what after we have got the result? This will be a great point where we will show the user in the View about it, so we will probably show a toast or snackbar or anything, just for example. So when we are done processing in the controller, whether the process was successful or error happened, we will fire up an event to the View so that it renders an appropriate message or dialog.

Momentum Event uses Stream under the hood

Lets demo this with an example, the boilerplate code is quite long but it sure does the trick. I advice that you create an event class you will use to listen to in the View. As an example lets create an event class to be fired when we perform authentication like signup, login to the UI

This is straight forward, in the View we simply switch..case the AuthEventAction that will give us an idea about which event has been fired and we can take appropriate action. Now lets see how we fire these event from Controllers

As you can see, all logic resides in the Controller, this keeps the code organized and clean, any changes i would want to add i simply jump here and start implementing it. sendEvent(..) is a momentum method that sends event and any listener will respond to it. Lets see how you can listen to these events and take appropriate action. This is where you add your stateful widget. A stateful widget is needed in order to listen for the event, no stream controllers here its automatically handled by the plugin, its done once in initMomentumState() its just like initState(..)

Thats it with events, you listen to AuthEvent in the initMomentumState and whenever you fire an event from your controllers, this will be invoked and appropriate action is taken. This approach i found easy, many boilerplate code but code is organized and clean, and each part of the app knows where it belongs.

There is a lot about this plugin that I didn’t cover in this intro, because its already long, i will cover as i go on with the series and a lot that i will keep exploring. More about momentum can be found

A full project about the complete demo app can be found at my github repository

Thank you for reading, if there is anything you want to know more or your thoughts about this article, please let me know in the comment section below. Until then, happy Fluttering 💙



Donald Chinhuru

An Undergraduate student studying towards BEng in Electronic Engineering with a keen interest on Software development. Currently pursuing everything Flutter 💙