Flutter Clean Architecture
Splitting a Flutter project into layers: domain, data and presentation. The examples are built on Riverpod 3, freezed and a sealed Result; the principles come from the Flutter team's official architecture guide. It ends with building a feature for real and migrating an existing screen.
Stages
Foundations: layers and the dependency rule
Architecture is not a set of folder names — it is a set of rules about which piece of code may talk to which. This stage covers the dependency rule, Flutter's two official layers, and the three ways to lay out folders.
Domain layer: models, contracts, use cases
The app's own vocabulary: domain models, their immutability, repository contracts, and when a use case is actually needed. This layer is pure Dart — it knows nothing about Flutter, HTTP or databases.
🔓 Recommended after: Foundations: layers and the dependency rule
Data layer: services, repositories, caching
How data reaches the app: services talk to the outside world, the repository acts as the source of truth, and caching and offline decisions are made in one place. Every "dirty" detail stays in this layer.
🔓 Recommended after: Domain layer: models, contracts, use cases
Error flow: Result, Failure and the UI
How an error travels between layers: when an exception is caught, why a Result is needed, how a Failure hierarchy is built, and what the user finally sees. This stage is built on Dart's sealed classes and exhaustive switch.
🔓 Recommended after: Data layer: services, repositories, caching
Presentation layer and dependency injection
The domain and the data are in place — now the screen. How UI state is modelled, why a notifier is a view model, where errors and side effects are handled, what logic may stay in a widget, and how dependencies are wired.
🔓 Recommended after: Error flow: Result, Failure and the UI
Practice: testing, building a feature, migrating
The theory is done. In this stage you write tests for each layer, build one feature end to end from scratch, migrate an existing messy screen into layers, and learn when to stop.
🔓 Recommended after: Presentation layer and dependency injection
📚 Sources and documentation
- Guide to app architectureofficialdocs.flutter.dev
This branch's primary source: the layers, how they relate, and the optional domain layer.
- Architecture recommendationsofficialdocs.flutter.dev
Every recommendation carries its weight: "strongly recommend", "recommend", "conditional". Check it before deciding.
- Case study: the Compass appofficialdocs.flutter.dev
The principles in a real codebase — folder structure, DI and per-layer testing each on its own page.