A production-ready Flutter application template featuring a modular, scalable architecture with comprehensive tooling, clean architecture principles, and enterprise-grade features.
Pattern M implements a feature-based clean architecture with clear separation of concerns, making it ideal for large-scale applications that require maintainability, testability, and team collaboration.
- Clean Architecture: Strict separation between data, domain, and presentation layers
- Feature-First Structure: Modular organization by features for better scalability
- Advanced Dependency Injection: Centralized DI container with provider overrides
- Multi-Environment Support: Built-in configurations for dev, staging, and production
- Comprehensive Error Handling: Type-safe failures using Freezed with pattern matching
- Enterprise Logging: Structured logging with environment-aware configurations
- Advanced Routing: Protected routes, shell routes, and auth-aware navigation
- Type-Safe State Management: Riverpod with code generation and compile-time safety
- Rich Context Extensions: Productivity helpers for common UI operations
- Internationalization Ready: Full i18n support with ARB files and type-safe access
lib/
βββ main.dart # App entry with DI and environment setup
βββ app.v.dart # Root widget with global configurations
βββ core/ # Core functionality and infrastructure
β βββ config/
β β βββ env.dart # Environment configuration and feature flags
β βββ constants/ # App-wide constants and enums
β βββ di/
β β βββ injection.dart # Dependency injection container
β βββ errors/
β β βββ exceptions.dart # Custom exceptions
β β βββ failures.dart # Freezed failure types
β β βββ failures.freezed.dart
β βββ extensions/ # Dart/Flutter extensions
β β βββ collection_extensions.dart
β β βββ context_extensions.dart # UI helpers (theme, navigation, dialogs)
β β βββ datetime_extensions.dart
β β βββ string_extensions.dart
β β βββ widget_extensions.dart
β βββ logger/
β β βββ logger.s.dart # Structured logging service
β βββ theme/
β β βββ app_theme.dart # Centralized theming
β βββ utils/
β βββ formatters.dart # Data formatting utilities
β βββ validators.dart # Input validation logic
βββ features/ # Feature modules (clean architecture)
β βββ auth/ # Authentication feature
β β βββ data/
β β β βββ datasources/ # Remote/local data sources
β β β βββ models/ # DTOs and serialization
β β β βββ repositories/ # Repository implementations
β β βββ domain/
β β β βββ entities/ # Business models
β β β βββ repositories/ # Repository contracts
β β β βββ usecases/ # Business logic
β β βββ presentation/
β β βββ providers/ # State management (.p.dart)
β β βββ screens/ # Page widgets (.v.dart)
β β βββ widgets/ # Feature-specific widgets
β βββ home/ # Home feature
β βββ settings/ # Settings feature
βββ l10n/ # Localization
β βββ app_en.arb # English translations
β βββ app_localizations.dart # Generated
β βββ app_localizations_en.dart
βββ shared/ # Cross-feature shared code
βββ data/
β βββ services/
β βββ storage.s.dart # Shared storage service
βββ domain/
β βββ models/ # Shared domain models
βββ presentation/
βββ providers/ # Global providers
β βββ auth.p.dart # Auth state provider
β βββ router.p.dart # Router with guards
β βββ theme.p.dart # Theme state
βββ widgets/ # Shared UI components
βββ error_screen.dart
βββ splash_screen.dart
Pattern M uses specific file suffixes for clarity and consistency:
.v.dart
- Views/Screens: UI components that represent full pages.p.dart
- Providers: Riverpod state management files.s.dart
- Services: Business logic services (storage, API, etc.).g.dart
- Generated: Auto-generated files (do not edit).freezed.dart
- Freezed: Generated immutable models
- Flutter SDK ^3.8.1
- Dart SDK (included with Flutter)
- Android Studio / VS Code with Flutter extensions
-
Clone the repository
git clone <repository-url> cd pattern_m
-
Install dependencies
flutter pub get
-
Generate code
dart run build_runner build --delete-conflicting-outputs
-
Run the application
flutter run
The project heavily uses code generation for boilerplate reduction:
# One-time generation
dart run build_runner build --delete-conflicting-outputs
# Watch mode for development (recommended)
dart run build_runner watch --delete-conflicting-outputs
Generated files include:
- Riverpod providers (
*.p.g.dart
) - Freezed models (
*.freezed.dart
,*.g.dart
) - JSON serialization (
*.g.dart
) - Localization (
app_localizations*.dart
)
The app supports multiple environments configured in lib/core/config/env.dart
:
// Automatic environment detection
- Debug mode β Development
- Release mode β Production
- Environment variable β Staging
// Environment-specific features
- API endpoints
- Feature flags
- Timeouts
- Analytics/Crash reporting
-
Create feature structure
lib/features/new_feature/ βββ data/ β βββ datasources/ β βββ models/ β βββ repositories/ βββ domain/ β βββ entities/ β βββ repositories/ β βββ usecases/ βββ presentation/ βββ providers/ βββ screens/ βββ widgets/
-
Implement layers bottom-up
- Start with domain entities and repositories
- Implement data layer with concrete repositories
- Create providers for state management
- Build UI screens and widgets
-
Register in DI container (if needed)
// In lib/core/di/injection.dart static Future<void> init() async { // Add your service initialization }
-
Add routes
// In lib/shared/presentation/providers/router.p.dart GoRoute( path: '/new-feature', name: 'newFeature', builder: (context, state) => const NewFeatureScreen(), ),
Provider with Code Generation
@riverpod
class FeatureName extends _$FeatureName {
@override
FeatureState build() => FeatureState.initial();
void updateState() {
state = state.copyWith(/* updates */);
}
}
Async Provider
@riverpod
Future<List<Item>> fetchItems(Ref ref) async {
final repository = ref.watch(itemRepositoryProvider);
return repository.getItems();
}
Pattern M uses type-safe error handling with Freezed:
// Define failures
@freezed
class Failure with _$Failure {
const factory Failure.server({
required String message,
int? statusCode,
}) = ServerFailure;
const factory Failure.network({
required String message,
}) = NetworkFailure;
}
// Handle failures
failure.when(
server: (message, code) => showServerError(message),
network: (message) => showNetworkError(message),
// ... other cases
);
The framework provides rich context extensions for common operations:
// Theme access
context.primaryColor
context.textTheme.headlineLarge
// Responsive design
if (context.isMobile) // < 600px
if (context.isTablet) // 600-1200px
if (context.isDesktop) // > 1200px
// Navigation helpers
context.showErrorSnackBar('Error message');
context.showSuccessSnackBar('Success!');
context.showLoadingDialog();
context.showAppBottomSheet(child: MySheet());
// Localization
context.l10n.welcomeMessage
flutter test
# With coverage
flutter test --coverage
# Generate coverage report
genhtml coverage/lcov.info -o coverage/html
test/
βββ core/
β βββ utils/
β βββ extensions/
βββ features/
β βββ auth/
β β βββ domain/
β β βββ data/
β β βββ presentation/
β βββ home/
βββ shared/
- Test use cases with mocked repositories
- Test providers with ProviderContainer
- Use
mocktail
ormockito
for mocking - Focus on business logic coverage
- Never commit sensitive data (API keys, secrets)
- Use environment variables for configuration
- Implement certificate pinning for production
- Enable obfuscation for release builds
- Regular dependency updates
- Minimum SDK: 21 (Android 5.0)
- Target SDK: Latest stable
- ProGuard rules for release builds
- Minimum deployment target: 12.0
- Swift version: Latest stable
- Code signing for distribution
- Responsive design support
- PWA capabilities
- SEO optimization ready
flutter run --debug
flutter run --dart-define=ENVIRONMENT=staging
# Android
flutter build apk --release --obfuscate --split-debug-info=debug_info
# iOS
flutter build ios --release --obfuscate --split-debug-info=debug_info
# Web
flutter build web --release --web-renderer canvaskit
-
Build runner conflicts
dart run build_runner clean dart run build_runner build --delete-conflicting-outputs
-
Pod install failures (iOS)
cd ios pod deintegrate pod install --repo-update
-
Gradle issues (Android)
cd android ./gradlew clean ./gradlew build
-
Architecture
- Keep layers independent
- Depend on abstractions, not concretions
- One feature, one folder
- Shared code in
/shared
-
State Management
- Use code generation for type safety
- Keep providers focused and testable
- Dispose resources properly
-
Error Handling
- Always handle failures explicitly
- Provide user-friendly error messages
- Log errors for debugging
-
Performance
- Use const constructors
- Implement proper list optimization
- Profile before optimizing
- Monitor app size
- Follow the established architecture
- Write tests for new features
- Update documentation
- Run linting:
flutter analyze
- Format code:
dart format .
- Create detailed pull requests
This project is a template and can be used freely for any purpose.