Skip to content

Folder Structure

This reference provides the complete folder structure for MOFA architecture projects, including file placement rules and organization principles.

For single applications, use this simplified structure:

lib/
β”œβ”€β”€ main.dart # Application entry point
β”œβ”€β”€ core/ # Core features shared across the app
β”‚ β”œβ”€β”€ auth/ # Authentication feature
β”‚ β”‚ β”œβ”€β”€ services/
β”‚ β”‚ β”‚ └── auth_service.dart
β”‚ β”‚ β”œβ”€β”€ models/
β”‚ β”‚ β”‚ └── auth_state.dart
β”‚ β”‚ └── providers/
β”‚ β”‚ └── auth_providers.dart
β”‚ β”œβ”€β”€ router/ # Navigation and routing
β”‚ β”‚ β”œβ”€β”€ app_router.dart
β”‚ β”‚ β”œβ”€β”€ routes.dart
β”‚ β”‚ └── pages/
β”‚ β”‚ β”œβ”€β”€ login_page.dart
β”‚ β”‚ └── home_page.dart
β”‚ β”œβ”€β”€ service_locators/ # Dependency injection
β”‚ β”‚ β”œβ”€β”€ client_providers.dart # GraphQL/HTTP clients
β”‚ β”‚ β”œβ”€β”€ datasource_providers.dart # Datasource instances
β”‚ β”‚ β”œβ”€β”€ repository_providers.dart # Repository implementations
β”‚ β”‚ └── service_providers.dart # Business logic services
β”‚ └── config/ # Configuration
β”‚ β”œβ”€β”€ flavor_config.dart
β”‚ └── app_config.dart
β”œβ”€β”€ features/ # Business features
β”‚ └── [feature_name]/ # Individual feature
β”‚ β”œβ”€β”€ ui/ # UI Layer
β”‚ β”‚ β”œβ”€β”€ screens/
β”‚ β”‚ β”‚ └── [feature]_screen.dart
β”‚ β”‚ β”œβ”€β”€ widgets/
β”‚ β”‚ β”‚ └── [feature]_widget.dart
β”‚ β”‚ └── notifiers/
β”‚ β”‚ └── [feature]_notifier.dart
β”‚ β”œβ”€β”€ services/ # Service Layer
β”‚ β”‚ β”œβ”€β”€ [feature]_service.dart
β”‚ β”‚ └── [feature]_orchestrator_service.dart
β”‚ β”œβ”€β”€ domain/ # Domain Layer
β”‚ β”‚ β”œβ”€β”€ models/
β”‚ β”‚ β”‚ └── [feature]_model.dart
β”‚ β”‚ β”œβ”€β”€ inputs/
β”‚ β”‚ β”‚ └── [feature]_inputs.dart
β”‚ β”‚ └── repositories/
β”‚ β”‚ └── i_[feature]_repository.dart
β”‚ └── datasource/ # Datasource Layer
β”‚ β”œβ”€β”€ [feature]_datasource.dart
β”‚ β”œβ”€β”€ [feature]_repository.dart
β”‚ β”œβ”€β”€ [feature]_datasource_module.dart
β”‚ β”œβ”€β”€ gql/
β”‚ β”‚ └── [feature]_operations.graphql
β”‚ └── strategies/
β”‚ β”œβ”€β”€ [feature]_request_strategies.dart
β”‚ └── [feature]_cache_strategies.dart
β”œβ”€β”€ services/ # Cross-cutting services
β”‚ β”œβ”€β”€ caching/
β”‚ β”‚ β”œβ”€β”€ secure_cache_service.dart
β”‚ β”‚ β”œβ”€β”€ simple_cache_service.dart
β”‚ β”‚ └── complex_cache_service.dart
β”‚ β”œβ”€β”€ error_handling/
β”‚ β”‚ └── error_handling_service.dart
β”‚ β”œβ”€β”€ logging/
β”‚ β”‚ └── logging_service.dart
β”‚ └── analytics/
β”‚ └── analytics_service.dart
└── packages/ # Generic packages
β”œβ”€β”€ i18n/
β”‚ β”œβ”€β”€ lib/
β”‚ β”‚ β”œβ”€β”€ src/
β”‚ β”‚ β”‚ β”œβ”€β”€ services/
β”‚ β”‚ β”‚ └── extensions/
β”‚ β”‚ └── i18n.dart
β”‚ └── pubspec.yaml
└── assets/
β”œβ”€β”€ lib/
β”‚ β”œβ”€β”€ src/
β”‚ β”‚ β”œβ”€β”€ services/
β”‚ β”‚ └── constants/
β”‚ └── assets.dart
└── pubspec.yaml
Monorepo Approach

For larger projects or multiple apps, use the monorepo structure with Pub Workspaces. This provides better separation of concerns and independent package development.

β”œβ”€β”€ pubspec.yaml # Root workspace configuration
β”œβ”€β”€ apps/
β”‚ └── [app_name]/ # Individual applications
β”‚ β”œβ”€β”€ lib/
β”‚ β”‚ β”œβ”€β”€ main.dart
β”‚ β”‚ └── src/
β”‚ β”‚ β”œβ”€β”€ core/ # App-specific core
β”‚ β”‚ β”‚ └── providers/
β”‚ β”‚ β”‚ β”œβ”€β”€ datasource_providers.dart
β”‚ β”‚ β”‚ └── service_providers.dart
β”‚ β”‚ └── features/
β”‚ β”‚ └── [feature]/
β”‚ β”‚ └── presentation/
β”‚ β”‚ β”œβ”€β”€ screens/
β”‚ β”‚ β”œβ”€β”€ widgets/
β”‚ β”‚ └── notifiers/
β”‚ └── pubspec.yaml
β”œβ”€β”€ packages/
β”‚ β”œβ”€β”€ domain/ # Domain layer package
β”‚ β”‚ β”œβ”€β”€ lib/
β”‚ β”‚ β”‚ β”œβ”€β”€ src/
β”‚ β”‚ β”‚ β”‚ β”œβ”€β”€ [feature]/
β”‚ β”‚ β”‚ β”‚ β”‚ β”œβ”€β”€ models/
β”‚ β”‚ β”‚ β”‚ β”‚ β”œβ”€β”€ inputs/
β”‚ β”‚ β”‚ β”‚ β”‚ β”œβ”€β”€ filters/
β”‚ β”‚ β”‚ β”‚ β”‚ β”œβ”€β”€ exceptions/
β”‚ β”‚ β”‚ β”‚ β”‚ └── repositories/
β”‚ β”‚ β”‚ β”‚ └── shared/
β”‚ β”‚ β”‚ └── domain.dart
β”‚ β”‚ └── pubspec.yaml
β”‚ β”œβ”€β”€ services/ # Service layer package
β”‚ β”‚ β”œβ”€β”€ lib/
β”‚ β”‚ β”‚ β”œβ”€β”€ src/
β”‚ β”‚ β”‚ β”‚ β”œβ”€β”€ [feature]/
β”‚ β”‚ β”‚ β”‚ β”‚ β”œβ”€β”€ [feature]_service.dart
β”‚ β”‚ β”‚ β”‚ β”‚ └── [feature]_orchestrator.dart
β”‚ β”‚ β”‚ β”‚ └── shared/
β”‚ β”‚ β”‚ β”‚ β”œβ”€β”€ caching/
β”‚ β”‚ β”‚ β”‚ β”œβ”€β”€ error_handling/
β”‚ β”‚ β”‚ β”‚ └── logging/
β”‚ β”‚ β”‚ └── services.dart
β”‚ β”‚ └── pubspec.yaml
β”‚ β”œβ”€β”€ datasource/ # Datasource layer package
β”‚ β”‚ β”œβ”€β”€ lib/
β”‚ β”‚ β”‚ β”œβ”€β”€ src/
β”‚ β”‚ β”‚ β”‚ β”œβ”€β”€ core/
β”‚ β”‚ β”‚ β”‚ β”‚ β”œβ”€β”€ remote/
β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ └── gql/
β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”œβ”€β”€ client/
β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ └── schema/
β”‚ β”‚ β”‚ β”‚ β”‚ └── local/
β”‚ β”‚ β”‚ β”‚ └── [feature]/
β”‚ β”‚ β”‚ β”‚ β”œβ”€β”€ remote/
β”‚ β”‚ β”‚ β”‚ β”‚ β”œβ”€β”€ gql/
β”‚ β”‚ β”‚ β”‚ β”‚ └── rest/
β”‚ β”‚ β”‚ β”‚ β”œβ”€β”€ repositories/
β”‚ β”‚ β”‚ β”‚ └── strategies/
β”‚ β”‚ β”‚ └── datasource.dart
β”‚ β”‚ └── pubspec.yaml
β”‚ β”œβ”€β”€ i18n/ # Internationalization package
β”‚ β”‚ β”œβ”€β”€ lib/
β”‚ β”‚ β”‚ β”œβ”€β”€ src/
β”‚ β”‚ β”‚ β”‚ β”œβ”€β”€ services/
β”‚ β”‚ β”‚ β”‚ β”œβ”€β”€ models/
β”‚ β”‚ β”‚ β”‚ └── extensions/
β”‚ β”‚ β”‚ └── i18n.dart
β”‚ β”‚ └── pubspec.yaml
β”‚ └── assets/ # Assets management package
β”‚ β”œβ”€β”€ lib/
β”‚ β”‚ β”œβ”€β”€ src/
β”‚ β”‚ β”‚ β”œβ”€β”€ services/
β”‚ β”‚ β”‚ └── constants/
β”‚ β”‚ └── assets.dart
β”‚ └── pubspec.yaml
└── tools/ # Development tools
β”œβ”€β”€ build_runner/
└── code_generation/
  • Models: [entity]_model.dart (e.g., user_model.dart)
  • Services: [feature]_service.dart (e.g., user_service.dart)
  • Orchestrators: [purpose]_orchestrator_service.dart (e.g., data_merge_orchestrator_service.dart)
  • Repositories: [entity]_repository.dart (e.g., user_repository.dart)
  • Repository Interfaces: i_[entity]_repository.dart (e.g., i_user_repository.dart)
  • Datasources: [entity]_datasource.dart (e.g., user_datasource.dart)
  • Notifiers: [feature]_notifier.dart (e.g., user_list_notifier.dart)
  • Screens: [feature]_screen.dart (e.g., user_list_screen.dart)
  • Widgets: [feature]_widget.dart (e.g., user_card_widget.dart)
  • Operations: [entity]_operations.graphql (e.g., user_operations.graphql)
  • Fragments: [entity]_fragments.graphql (e.g., user_fragments.graphql)
  • Unit Tests: [class_name]_test.dart (e.g., user_service_test.dart)
  • Widget Tests: [widget_name]_test.dart (e.g., user_list_widget_test.dart)
  • Integration Tests: [feature]_integration_test.dart
  • Purpose: Contains features that need to be imported by other features
  • Rule: If a feature needs to be imported by another feature, it belongs in core
  • Components: Auth, Router, Service Locators, Configuration
  • Independence: Features must not import other features directly
  • Self-contained: Each feature contains all its layers (UI, Services, Domain, Datasource)
  • Shared Logic: Extract shared logic to services or core modules
  • Generic Packages: Must be business-logic independent
  • Domain Package: Contains only pure models and interfaces
  • Service Package: Contains all business logic
  • Datasource Package: Contains only data access logic
// UI Layer
import 'package:domain/domain.dart'; // βœ… Domain models
import 'package:services/services.dart'; // βœ… Business logic
import '../core/auth/auth_service.dart'; // βœ… Core features
import 'package:i18n/i18n.dart'; // βœ… Generic packages
// Service Layer
import 'package:domain/domain.dart'; // βœ… Domain models
import 'package:datasource/repositories.dart'; // βœ… Repository implementations
import '../core/service_locators.dart'; // βœ… Service locators
// Domain Layer
// No imports from other layers // βœ… Pure domain
// Datasource Layer
import 'package:domain/domain.dart'; // βœ… Domain interfaces only
// UI Layer
import 'package:datasource/datasource.dart'; // ❌ Skip service layer
// Domain Layer
import 'package:services/services.dart'; // ❌ Domain depends on services
import 'package:datasource/datasource.dart'; // ❌ Domain depends on datasource
// Datasource Layer
import 'package:services/services.dart'; // ❌ Circular dependency
// Features
import '../other_feature/feature.dart'; // ❌ Feature-to-feature dependency
test/
β”œβ”€β”€ unit/ # Unit tests
β”‚ β”œβ”€β”€ services/
β”‚ β”œβ”€β”€ repositories/
β”‚ └── domain/
β”œβ”€β”€ widget/ # Widget tests
β”‚ β”œβ”€β”€ screens/
β”‚ β”œβ”€β”€ components/
β”‚ └── forms/
β”œβ”€β”€ integration/ # Integration tests
β”‚ └── features/
└── helpers/ # Test utilities
β”œβ”€β”€ mocks/
β”œβ”€β”€ fixtures/
└── test_utils.dart

This folder structure ensures clear separation of concerns, maintainable code organization, and proper architectural boundaries in MOFA architecture projects.