When scaling Flutter applications from a hobby project to an enterprise-grade codebase, teams almost always hit one of two architectural extremes:
- The Monolithic Mess: All business logic, HTTP clients, and UI widgets are dumped into one or two folders. Global state is everywhere, modules are tightly coupled, and making a change in one screen breaks three others.
- The “Over-Abstracted” Clean Architecture: In an attempt to follow Clean Architecture strictly, developers create 15 nested folders (data sources, raw DTOs, mappers, domain entities, use cases, presenters) just to display a simple settings toggle.
To solve this dilemma, I designed and open-sourced Flutter Production Starter — a modular, feature-first monorepo template built for real-world development speed and long-term maintainability.
In this article, I’ll walk you through the architectural principles, dependency boundaries, and modern stack choices behind this starter.
🧱 The Core Philosophy: “LEGO” Modular Boundaries
The fundamental rule of this architecture is LEGO Modularity: every feature should be a self-contained building block with a clear responsibility, minimal coupling, and an intentional public API.
┌───────────────────────────────────────────────┐
│ APPLICATION │
│ Bootstrap • Config • DI • Routing • Observers │
└───────────────────────┬───────────────────────┘
│
▼
┌───────────────────────────────────────────────┐
│ FEATURE MODULES │
│ Auth │ Profile │ Home │ Settings │ Payments │
└───────────────────────┬───────────────────────┘
│
▼
┌───────────────────────────────────────────────┐
│ SHARED PACKAGES │
│ app_core │ network │ storage │ design_system │
└───────────────────────────────────────────────┘
Enter fullscreen mode Exit fullscreen mode
1. Feature-First Colocation
Instead of organizing the entire codebase by layer (data/, domain/, presentation/), all code belonging to a business capability is colocated in apps/mobile/lib/features/<feature>/.
2. Public API Barrel Files
A feature must never reach into the private implementation files of another feature. Instead, features expose only intentional contracts through their root barrel file:
// ✅ Clean: Importing through the feature's public API
import 'package:mobile/features/auth/auth.dart';
// ❌ Forbidden: Deep import into private data sources
import 'package:mobile/features/auth/data/datasources/auth_remote_data_source.dart';
Enter fullscreen mode Exit fullscreen mode
⚖️ Pragmatic Clean Architecture (3 Complexity Tiers)
Clean Architecture should be applied where complexity justifies it, not blindly everywhere:
-
Tier 1 — Simple Feature (e.g.
settings): Presentation + State only. No need for use cases or DTOs when updating a local theme mode. -
Tier 2 — Medium Feature (e.g.
profile): Entity contract, Repository implementation, DTO mapping, and presentation. -
Tier 3 — Complex Feature (e.g.
auth): Complete Clean Architecture with Use Cases, Remote Data Sources, Token Storage, and Route Guards. -
Pluggability (e.g.
auth_v2): Proves you can swap out an entire feature’s underlying data/service layer behind its domain interface via Dependency Injection without modifying consumer code.
📁 Monorepo Structure with Melos
Managing multiple packages in a single repository is powered by Melos:
/
├── apps/
│ └── mobile/ # Main app (Bootstrap, Environments, DI, Routes, Features)
├── packages/
│ ├── app_core/ # Result<T> monad, domain Failure taxonomy, Sanitized AppLogger
│ ├── app_network/ # Centralized Dio, interceptors, error mappers, ApiClient
│ ├── app_storage/ # SecureStorage, KeyValueStorage, TTL MemoryCache
│ ├── design_system/ # Tokens (Spacing, Radius), Light/Dark themes, Primitives
│ └── app_lints/ # Strict linting & static analysis configuration
├── melos.yaml # Monorepo scripts (analyze, test, format, run)
└── ARCHITECTURE.md # Architectural guide
Enter fullscreen mode Exit fullscreen mode
Why Dedicated Shared Packages?
-
app_core: Pure Dart abstractions (Result<T>,Failure, sanitized logger) with zero Flutter/UI dependencies. -
app_network: CentralizedDioinstance. Features never instantiateDio()directly. It owns token injection, exponential backoff retries, and automatic sensitive data redaction (passwords and bearer tokens are never logged in plain text). -
design_system: Standalone visual primitives, tokens (AppSpacing,AppRadius,AppDurations), and complete Material 3 Light/Dark themes.
⚡ Modern Technology Stack
Capability Library / Solution Rationale Routingkaisel: ^1.1.0
Strongly-typed declarative routing and route guards (AuthRouteGuard).
State
bloc_signals + signals_flutter
Fine-grained reactive signals without boilerplate.
DI
get_it + injectable
Constructor injection with compile-time code generation.
Networking
dio: ^5.11.0
Enterprise HTTP client encapsulated in app_network.
Models
freezed
Immutable union states, DTOs, and copyable entities.
Feedback
toastification: ^3.2.0
Clean presentation-only feedback and snackbars.
🛡️ Functional Error Pipeline
Instead of leaking raw HTTP exceptions into widgets, the app uses a functional Result<T> and Failure hierarchy:
// Fetching data cleanly with functional Result
final result = await loginUseCase(email: email, password: password);
result.fold(
onSuccess: (session) => router.toHome(),
onFailure: (failure) {
// FailureMessageResolver resolves friendly messages
feedback.showError(context, failureResolver.resolve(failure));
},
);
Enter fullscreen mode Exit fullscreen mode
🧪 Testing & CI
A starter is only as good as its verification. Every package in the monorepo has automated tests and strict linting:
# Run tests across all 6 packages simultaneously
melos run test
# Check static analysis across the entire monorepo
melos run analyze
Enter fullscreen mode Exit fullscreen mode
GitHub Actions CI is already pre-configured (.github/workflows/ci.yml) to validate every commit and PR automatically.
🚀 Try It Out
The entire template is open-source under the MIT License!
👉 GitHub Repository: https://github.com/Ali-El-Khatib/flutter-production-starter
# Clone the repository
git clone https://github.com/Ali-El-Khatib/flutter-production-starter.git
# Bootstrap packages
cd flutter-production-starter
melos bootstrap
# Run the app
melos run run:dev
Enter fullscreen mode Exit fullscreen mode
If you find this architecture helpful for your Flutter projects, feel free to give it a ⭐ on GitHub and share your thoughts in the comments below! What architectural patterns do you prefer for large-scale Flutter apps?