flutter · 8 min read

A practical guide to Flutter Clean Architecture

Clean Architecture is most useful when business rules need to survive changes to your UI or data source. Its defining feature is dependency direction, not the number of directories. A shopping app can change from an HTTP API to a local cache without rewriting checkout rules if those rules depend on an interface.

How the pieces connect

PresentationDomain contractsData implements contracts

A starting folder structure

lib/
  features/checkout/
    presentation/checkout_page.dart
    domain/place_order.dart
    domain/order_repository.dart
    data/api_order_repository.dart
  core/dependency_injection/container.dart

Follow one operation through the layers

A page sends a checkout action to a BLoC or notifier. The state owner invokes PlaceOrder with validated input. PlaceOrder depends on OrderRepository, a domain interface. The data implementation translates API responses into domain values. The composition root creates these objects and supplies the implementation; the domain never imports Dio or Flutter widgets.

Start with boundaries you can test

Test the order total, unavailable inventory, and retry policy using a fake repository. Widget tests should assert loading, success, and error rendering. Integration tests cover the real serialization and API contract. This separation gives failures a location and keeps business tests fast.

When the extra layers pay off

Use this approach for offline synchronization, multiple data sources, substantial business rules, or teams that work independently on features. A prototype displaying one endpoint may be better served by feature-first folders and a repository. Add a use case when it coordinates rules; a class that only forwards one call may add little value.

Avoid DTOs escaping into widgets

API models describe the remote contract and may contain nullable or transport-specific fields. Translate them at the data boundary. Keep errors meaningful: a domain failure such as out-of-stock should not be reduced to a generic HTTP exception. Do not make presentation construct concrete remote repositories.

Try this configuration

Clean Architecture · BLoC · Dio · GetIt · GoRouter

The generator includes a working counter example with a repository contract, selected dependencies, navigation, and local setup instructions. Extend the example around your own domain before shipping.

Configure your Flutter project →

Continue reading

Primary references

Flutter application architecture documentation explains architectural recommendations. For state APIs, consult Riverpod documentation and BLoC documentation.