Entitas for Flutter

Alternative way of building reactive, testable and easy to evolve apps with Flutter.

This is going to be a very long article, but it will be totally worth it. 🤞

I assume you already have working understanding of Flutter and you might even have seen this presentation by the Flutter team:

This article will be based on examples and concepts from this presentation. It can be help-full to watch this presentation first, but it is not necessary, as I will give a gradual introduction anyways.

First of all, WTF is Entitas?

Entitas is an implementation of Entity Component System pattern (ECS for short), which focus on developer experience. The most popular implementation of Entitas (Entitas-CSharp) earned over 3K stars on Github and is adopted by many game development studios, big and small.

The main principle of a pure ECS application is:

Separation of state from behaviour

Flutter kind of follows this principle, by separating between Stateless and Stateful widgets, but it is a bit clumsy IMHO. For example, here is the naive implementation of Flutter Counter App as discussed in the “Reactive mobile apps” talk:

Let’s have a walk through the defined classes.

MyApp is a simple stateless widget, which declares the root of the app. All good and dandy! This class just represents the widget hierarchy, completely declarative, clean as a whistle.

MyHomePage is a stateful widget and it is just boilerplate, it defines a “link” to _MyHomePageState class and enables the caller to provide title to the state class.

Now _MyHomePageState is where we mix state an behaviour, even though from the naming, you might assume it only stores state.

That class does store the count in the _counter variable, but it also defines the incrementation logic in _increment method and it has to override build method which provides the logic how to build the child of the stateful widget.

What is wrong with mixing state and behaviour?

First of all, mixing state with behaviour introduces coupling and information hiding, which makes it hard to unit test. It is also easier to build up a rigid application, which will be very hard to evolve (introduce new features). It is however mostly easier to write mixed code and it is also possible to mix state and behaviour in a way, which makes unit testing and refactoring still possible.

In this article we will first implement examples, where the state and behaviour is slightly mixed and than refactor it to be decoupled (as much as possible).