Flutter Project Directory Structures: 17 Architectures and When to Use Them
Explore 17 popular Flutter project directory structures, including Feature-Driven, Clean Architecture, MVVM, BLoC, Riverpod, Vertical Slice, DDD, and Monorepo approaches. Learn how each structure works, its advantages and trade-offs, and which architecture fits your Flutter project.
Here's the collection of common Flutter project directory structures, from simple projects to large-scale production applications.
1. Flat / Simple Structureβ
Best for small apps, prototypes, tutorials, and simple utilities.
lib/
βββ main.dart
βββ screens/
β βββ home_screen.dart
β βββ settings_screen.dart
β βββ profile_screen.dart
βββ widgets/
β βββ app_button.dart
β βββ app_card.dart
βββ models/
β βββ user.dart
βββ services/
β βββ api_service.dart
βββ utils/
β βββ helpers.dart
βββ constants/
βββ app_constants.dart
Characteristicsβ
- Very easy to understand
- Minimal architectural overhead
- Suitable for small applications
- Becomes difficult to maintain as the application grows
2. Feature-Driven Structureβ
Organizes code around business features rather than technical layers.
lib/
βββ main.dart
βββ core/
β βββ constants/
β βββ errors/
β βββ network/
β βββ routing/
β βββ theme/
β βββ utils/
βββ features/
β βββ authentication/
β β βββ data/
β β βββ domain/
β β βββ presentation/
β βββ home/
β β βββ data/
β β βββ domain/
β β βββ presentation/
β βββ profile/
β β βββ data/
β β βββ domain/
β β βββ presentation/
β βββ settings/
β βββ data/
β βββ domain/
β βββ presentation/
βββ shared/
βββ widgets/
βββ models/
βββ extensions/
Characteristicsβ
- Feature boundaries are clear
- Easy to scale
- Features can be developed independently
- Excellent default for medium and large applications
3. Layer-Driven / Technical-Layer Structureβ
Organizes files according to their technical responsibility.
lib/
βββ main.dart
βββ presentation/
β βββ screens/
β βββ widgets/
β βββ controllers/
βββ domain/
β βββ entities/
β βββ repositories/
β βββ use_cases/
βββ data/
β βββ models/
β βββ repositories/
β βββ datasources/
β βββ services/
βββ core/
β βββ constants/
β βββ errors/
β βββ network/
β βββ routing/
β βββ utils/
βββ config/
βββ environment/
βββ app_config.dart
Characteristicsβ
- Clear separation of technical responsibilities
- Works well with Clean Architecture
- Easy to understand for developers familiar with layered architecture
- Can become difficult to navigate when many features exist
4. Clean Architectureβ
Separates presentation, business logic, and external data sources.
lib/
βββ main.dart
βββ core/
β βββ error/
β βββ network/
β βββ usecases/
β βββ utils/
β βββ constants/
βββ features/
β βββ authentication/
β βββ data/
β β βββ datasources/
β β β βββ auth_local_datasource.dart
β β β βββ auth_remote_datasource.dart
β β βββ models/
β β β βββ user_model.dart
β β βββ repositories/
β β βββ auth_repository_impl.dart
β βββ domain/
β β βββ entities/
β β β βββ user.dart
β β βββ repositories/
β β β βββ auth_repository.dart
β β βββ usecases/
β β βββ login.dart
β β βββ logout.dart
β βββ presentation/
β βββ pages/
β βββ widgets/
β βββ bloc/
βββ injection_container.dart
Characteristicsβ
- Strong separation of concerns
- Business rules are independent of Flutter/UI
- Highly testable
- Suitable for complex applications
- More boilerplate than simpler structures
5. Clean Architecture + Feature-Firstβ
A common production-oriented combination of feature-first organization and Clean Architecture.
lib/
βββ main.dart
βββ app/
β βββ app.dart
β βββ router.dart
β βββ theme/
βββ core/
β βββ constants/
β βββ errors/
β βββ extensions/
β βββ network/
β βββ storage/
β βββ utils/
β βββ widgets/
βββ features/
β βββ auth/
β β βββ data/
β β βββ domain/
β β βββ presentation/
β βββ home/
β β βββ data/
β β βββ domain/
β β βββ presentation/
β βββ settings/
β βββ data/
β βββ domain/
β βββ presentation/
βββ di/
βββ injection.dart
Characteristicsβ
This is often a strong choice for large Flutter applications because:
features/
β
domain
β
data
presentation
β
domain
Features remain isolated while the architectural boundaries remain explicit.
6. MVVM Structureβ
Uses Model-View-ViewModel.
lib/
βββ main.dart
βββ models/
β βββ user.dart
β βββ product.dart
βββ views/
β βββ home/
β β βββ home_view.dart
β βββ login/
β β βββ login_view.dart
β βββ profile/
β βββ profile_view.dart
βββ viewmodels/
β βββ home_viewmodel.dart
β βββ login_viewmodel.dart
β βββ profile_viewmodel.dart
βββ services/
β βββ api_service.dart
β βββ auth_service.dart
βββ repositories/
βββ user_repository.dart
βββ product_repository.dart
Characteristicsβ
- UI is separated from presentation logic
- ViewModels manage state and UI-facing logic
- Familiar architecture for developers from other platforms
- Works well with Provider, Riverpod, ChangeNotifier, etc.
7. MVC Structureβ
Uses Model-View-Controller.
lib/
βββ main.dart
βββ models/
β βββ user.dart
β βββ product.dart
βββ views/
β βββ home_view.dart
β βββ login_view.dart
β βββ profile_view.dart
βββ controllers/
β βββ auth_controller.dart
β βββ home_controller.dart
β βββ profile_controller.dart
βββ services/
β βββ api_service.dart
βββ utils/
βββ helpers.dart
Characteristicsβ
- Simple mental model
- Good for small-to-medium projects
- Controllers can become too large if business logic is not separated properly
8. MVI Structureβ
Uses Model-View-Intent.
lib/
βββ main.dart
βββ features/
β βββ login/
β βββ model/
β β βββ login_state.dart
β β βββ login_intent.dart
β βββ view/
β β βββ login_page.dart
β βββ intent/
β βββ login_intent_handler.dart
βββ core/
β βββ network/
β βββ utils/
βββ app/
βββ app.dart
Characteristicsβ
- State-driven architecture
- Explicit user intents/actions
- Useful for complex reactive interfaces
- Works particularly well with unidirectional data flow
9. BLoC / Cubit Feature Structureβ
Organizes BLoC state management around features.
lib/
βββ main.dart
βββ core/
β βββ constants/
β βββ errors/
β βββ network/
β βββ widgets/
βββ features/
β βββ auth/
β β βββ bloc/
β β β βββ auth_bloc.dart
β β β βββ auth_event.dart
β β β βββ auth_state.dart
β β βββ models/
β β βββ repositories/
β β βββ pages/
β β βββ widgets/
β βββ home/
β β βββ bloc/
β β βββ models/
β β βββ pages/
β β βββ widgets/
β βββ profile/
β βββ cubit/
β βββ models/
β βββ pages/
β βββ widgets/
βββ app/
βββ app.dart
βββ router.dart
Characteristicsβ
- Natural structure for
flutter_bloc - Keeps state-management code close to its feature
- Easy to test
- Avoids one giant global BLoC directory
10. Riverpod Feature Structureβ
Organizes Riverpod providers alongside their features.
lib/
βββ main.dart
βββ app/
β βββ app.dart
β βββ router.dart
β βββ theme/
βββ core/
β βββ network/
β βββ storage/
β βββ utils/
βββ features/
β βββ auth/
β β βββ data/
β β βββ models/
β β βββ providers/
β β βββ screens/
β β βββ widgets/
β βββ products/
β β βββ data/
β β βββ models/
β β βββ providers/
β β βββ screens/
β β βββ widgets/
β βββ cart/
β βββ models/
β βββ providers/
β βββ screens/
β βββ widgets/
βββ shared/
βββ widgets/
Characteristicsβ
- Providers remain close to the state they manage
- Good fit for Riverpod
- Scales well with feature-first architecture
11. Repository Patternβ
Separates data access behind repositories.
lib/
βββ main.dart
βββ models/
β βββ user.dart
β βββ product.dart
βββ repositories/
β βββ user_repository.dart
β βββ product_repository.dart
βββ datasources/
β βββ remote/
β β βββ api_datasource.dart
β βββ local/
β βββ database_datasource.dart
βββ services/
β βββ api_service.dart
β βββ storage_service.dart
βββ screens/
βββ widgets/
Characteristicsβ
Useful when an application has multiple data sources:
UI
β
Repository
β
ββββββββββββββββ
β β
Local Remote
Data API
12. Package-by-Feature / Modular Structureβ
Useful for very large applications or teams.
packages/
βββ app/
β βββ lib/
βββ authentication/
β βββ lib/
β βββ authentication.dart
β βββ src/
βββ user/
β βββ lib/
β βββ user.dart
β βββ src/
βββ products/
β βββ lib/
β βββ products.dart
β βββ src/
βββ payments/
β βββ lib/
β βββ payments.dart
β βββ src/
βββ design_system/
βββ lib/
βββ design_system.dart
βββ src/
apps/
βββ mobile/
βββ lib/
βββ main.dart
Characteristicsβ
- Strong module boundaries
- Features can become independent Dart/Flutter packages
- Excellent for large teams
- Useful for monorepos
- More setup and tooling required
13. Monorepo Structureβ
A full repository containing applications and shared packages.
project/
βββ apps/
β βββ mobile/
β β βββ android/
β β βββ ios/
β β βββ lib/
β βββ web/
β βββ admin/
βββ packages/
β βββ core/
β βββ networking/
β βββ authentication/
β βββ database/
β βββ design_system/
β βββ shared_models/
βββ tools/
βββ scripts/
βββ melos.yaml
βββ pubspec.yaml
Characteristicsβ
- Shared packages across multiple Flutter applications
- Good for mobile + web + desktop + admin products
- Suitable for large organizations
- Often paired with a monorepo tool such as Melos
14. Design-System-Oriented Structureβ
Useful when the application has a large reusable UI system.
lib/
βββ main.dart
βββ app/
β βββ app.dart
β βββ router.dart
β βββ theme/
βββ design_system/
β βββ tokens/
β β βββ colors.dart
β β βββ spacing.dart
β β βββ typography.dart
β β βββ radii.dart
β βββ components/
β β βββ buttons/
β β βββ cards/
β β βββ dialogs/
β β βββ inputs/
β β βββ navigation/
β βββ extensions/
βββ features/
β βββ home/
β βββ profile/
β βββ settings/
βββ core/
Characteristicsβ
- Centralized visual language
- Excellent for product families
- Makes UI consistency easier
- Particularly useful for large applications
15. Domain-Driven Design (DDD)β
Organizes the application around business domains and bounded contexts.
lib/
βββ main.dart
βββ shared/
β βββ kernel/
β βββ value_objects/
β βββ exceptions/
βββ domains/
β βββ identity/
β β βββ domain/
β β βββ application/
β β βββ infrastructure/
β β βββ presentation/
β βββ catalog/
β β βββ domain/
β β βββ application/
β β βββ infrastructure/
β β βββ presentation/
β βββ ordering/
β βββ domain/
β βββ application/
β βββ infrastructure/
β βββ presentation/
βββ app/
βββ routing/
βββ dependency_injection/
Characteristicsβ
- Models the business domain explicitly
- Useful for complex business applications
- Strong boundaries between domains
- Usually unnecessary for small apps
16. Vertical Slice Architectureβ
Each feature contains everything needed to implement a complete user-facing slice.
lib/
βββ main.dart
βββ core/
β βββ networking/
β βββ database/
β βββ routing/
βββ features/
β βββ login/
β β βββ login_page.dart
β β βββ login_controller.dart
β β βββ login_state.dart
β β βββ login_repository.dart
β β βββ login_models.dart
β βββ register/
β β βββ register_page.dart
β β βββ register_controller.dart
β β βββ register_state.dart
β β βββ register_repository.dart
β βββ checkout/
β βββ checkout_page.dart
β βββ checkout_controller.dart
β βββ checkout_state.dart
β βββ checkout_repository.dart
βββ shared/
βββ widgets/
βββ extensions/
Characteristicsβ
- Feature code is highly localized
- Reduces cross-project dependencies
- Excellent for rapidly evolving applications
- Similar in spirit to feature-first architecture, but slices can contain the complete flow rather than following strict global layers
17. Hybrid Architectureβ
Combines several approaches.
lib/
βββ main.dart
βββ app/
β βββ app.dart
β βββ router.dart
β βββ theme/
β βββ dependency_injection.dart
βββ core/
β βββ constants/
β βββ errors/
β βββ network/
β βββ storage/
β βββ extensions/
β βββ widgets/
βββ features/
β βββ auth/
β β βββ data/
β β βββ domain/
β β βββ presentation/
β βββ news/
β β βββ data/
β β βββ domain/
β β βββ presentation/
β βββ settings/
β βββ data/
β βββ domain/
β βββ presentation/
βββ shared/
β βββ models/
β βββ widgets/
β βββ services/
βββ generated/
Characteristicsβ
This is often the most practical approach:
- Feature-first at the top level
- Clean Architecture inside complex features
- Shared infrastructure in
core - Reusable application components in
shared - App-wide configuration in
app
Quick Comparison
| Structure | Small App | Medium App | Large App | Complexity |
|---|---|---|---|---|
| Flat | Excellent | Poor | Poor | Very Low |
| Layer-Driven | Good | Good | Fair | Low |
| Feature-Driven | Good | Excellent | Excellent | Medium |
| MVC | Good | Good | Fair | Low |
| MVVM | Good | Excellent | Good | Medium |
| BLoC + Features | Good | Excellent | Excellent | Medium |
| Riverpod + Features | Good | Excellent | Excellent | Medium |
| Clean Architecture | Fair | Excellent | Excellent | High |
| Feature + Clean Architecture | Fair | Excellent | Excellent | High |
| Repository Pattern | Good | Excellent | Excellent | Medium |
| Vertical Slice | Good | Excellent | Excellent | Medium |
| DDD | Poor | Good | Excellent | Very High |
| Modular / Packages | Poor | Good | Excellent | High |
| Monorepo | Poor | Good | Excellent | Very High |
| Design System | Fair | Excellent | Excellent | Medium |
| Hybrid | Excellent | Excellent | Excellent | MediumβHigh |
Recommended Choices
Small Utility / Prototypeβ
lib/
βββ main.dart
βββ screens/
βββ widgets/
βββ models/
βββ services/
Use this when the project is small enough that architecture would otherwise become overhead.
Normal Production Appβ
lib/
βββ app/
βββ core/
βββ features/
βββ shared/
Use Feature-Driven Architecture as the primary organization.
Large Production Appβ
lib/
βββ app/
βββ core/
βββ features/
β βββ feature_a/
β β βββ data/
β β βββ domain/
β β βββ presentation/
β βββ feature_b/
β βββ data/
β βββ domain/
β βββ presentation/
βββ shared/
Use Feature-First + Clean Architecture.
Multiple Apps / Large Teamβ
apps/
βββ mobile/
βββ web/
βββ admin/
packages/
βββ core/
βββ design_system/
βββ authentication/
βββ networking/
βββ shared_models/
Use a Monorepo + Modular Packages + Feature-First Architecture.
A Useful Rule of Thumb
Instead of asking:
"Which architecture is the best?"
Ask:
"Where will this project become difficult to maintain?"
For most Flutter projects, a practical progression is:
Small
β
Flat
β
Feature-Driven
β
Feature-Driven + State Management
β
Feature-Driven + Clean Architecture
β
Modular / Monorepo
Large
Do not introduce Clean Architecture, DDD, or a monorepo simply because they are popular. Add architectural complexity when the project's size, team structure, domain complexity, testing requirements, or number of applications actually justifies it.