Clean Architecture is a software design pattern based on the concept of separation of concerns. Each component provides a simple functionality, with a predictable set of dependencies. It facilitates testing of individual components and eases management of complex applications with simple rules.
In this post, we will discuss how we applied Clean Architecture to a mobile application on a client project. It brought new challenges and new learnings about concepts and about how to apply them to a mobile application.
Mobile application setup
As there were no features that required native functionalities and time to market was of the essence for our client, we decided to use Flutter, a framework created by Google. A single codebase would make it simple and quick to release an application with the same features for both iOS and Android.
Flutter is written in Dart, a type-safe programming language with static typing. Flutter was actively maintained, in constant evolution with frequent releases.

Application running from Android Studio
First impressions
In the beginning, Clean Architecture required more attention when starting a task. We had to identify the concepts necessary to implement the task: models, data sources, repositories, use cases, etc. It seemed an extra hassle: we had to write interfaces, define data models before starting to write the functionality specified in the task.
Clean Architecture is based on the concept of separation of concerns. Each component represents one concern, and a set of closely related functionality. This brings a few development advantages:
- It makes it easy to write unit and integration tests. Testing one component shouldn’t depend on the implementation details of other components.
- Having integration tests allows us to test more complex scenarios. For example, we could use a data source to simulate different failure statuses.
- It allows us to start developing frontend features before the backend counterpart was ready.
Not everything was perfect, there were minor inconveniences mostly related to the Flutter framework:
- Some Flutter packages broke due to changes in the framework. Changes in the dart language required modifications in those packages before we could update to a new Flutter version.
- New native features didn’t have a Flutter package immediately when they were released.
Improved team organization
Our team’s initial goal was to release a version within a few months. This wouldn’t have been possible if we had to implement every feature twice, once for Android and one for iOS. The release was a success and we continued developing the application for several years, adding new features, and improving existing features.
During the project life, the team went through several configurations to accommodate client requests and personnel changes.
Using Clean Architecture allowed us to have a flexible team structure:
- Quick onboarding of new team members.
- Several developers could work in parallel on different simple features.
- Two or more developers could work together to implement more complex features.
Conclusion
I think Clean Architecture is a great choice for mobile projects. It could appear too complex initially but once familiarized it provides a sense of order, fosters a consistent code base and accelerates new member ramp ups. There are less merge conflicts and programmers can invest more time on building new features.
It was a great experience using Clean Architecture and Flutter to deliver a complex mobile application in time for both iOS and Android.
References
- The Clean Architecture by Robert C. Martin (Uncle Bob)
- Flutter TDD Clean Architecture Course by Matt Rešetár
- Clean Architecture: Applying with Flutter by Rubem Vasconcelos
- Flutter Clean Architecture Series by AbdulMuaz Aqeel
- Bloc, A predictable state management library for Dart