How to create a State Management library
Sandro Maglione
Get in touch with meMobile development
27 December 2023
•5 min read
Sandro Maglione
Mobile development
I started working on implementing a state machine.
It worked great. But that was not enough. How can I make it usable?
I ended up creating a state management library. Here is how 👇
Tech stack
- dart: the state machine is implemented in plain dart (with some wizardy around generic types and type safety)
- Flutter: the state machine was working with dart, I then wrote some code to use it with Flutter as well
Setup
Creating a new package in dart is just one command away:
I started there. Nothing more nothing less. After all this is plain dart.
Get started
Now, initially my intention was making a state machine.
I already knew well enough the theory behind state machines, and I also had my fair bit of practice with them (XState 👈).
What I didn't expected was my detour into state management,
Stream
,Provider
, and how to connect state changes with a Flutter widget.
This was all a practical experiment, how to connect all the pieces together in a working library.
Let's dive into the implementation!
There is more.
Every week I build a new open source project, with a new language or library, and teach you how I did it, what I learned, and how you can do the same. Join me and other 600+ readers.
Implementation
As the project evolved we can pinpoint 3 distinct phases 👇
Implementing a State Machine
Phase 1: State Machine.
Main challenge: how to model a type safe, usable, and flexible state machine?
The type safe part was especially important. This requires some tricky code around abstract class
, generic types, and nullable/optional parameters.
State machines are not enough, entering Statecharts
A state machines has a final list of states and events to transition between states. Not enough in practice.
Welcome Statecharts!
A statechart expands over a state machine to add actions, context, concurrency, and much more.
This makes a state machine more useful in practice.
I added another generic parameter, with a (full) new refactoring of states and events:
It works. How about streaming state in Flutter?
The machine was working great. But it was not of much use in practice.
How can I take this thing to the next level? How about an integration with Flutter?
Now, I never had some real practice using Stream
in dart. This step required some serious engineering genius.
Solution: Copy-paste everything from the
bloc
package code, try to understand it, and make it work for my machine.
I copied everything from the bloc package with the goal of understanding how to stream states
This is why open source is awesome! I copied all the code from bloc
, and gradually removed features until I reached the core of how streaming works.
As you may have guessed, it worked!
I then did the same with flutter_bloc
. At the end I created a state management library based on Provider
that listens and streams states changes from a state machine.
👉 For all the details and code snippets you can read the full article containing all the details of the implementation.
Takeaways
- State machines (Statecharts) are awesome for modeling and managing state
- Less theory and more practice: when you want to learn a new API dive deep into existing open source code, it will teach you way more than just watching Youtube videos
- State management in Flutter is easy: a class has some internal state and uses a
Stream
to push out state updates, Flutter listens and updates the widget. Nothing more than that - Dart's type system is powerful in its own way: the state machine is completely type safe
At the end I have a working open source prototype. I don't intend to expand and publish this as a package on pub.dev.
Since it's open source anyone can pick it up and continue the work.
See you next 👋