A scalable Flutter starter kit for medium-to-large apps with:
- Feature-first structure
- Clean architecture boundaries
- Riverpod dependency injection and state management
- GoRouter app shell navigation
- Dio networking
- Drift local caching
- Demo auth and settings modules
- A complete reference feature for remote + local data flow
This project is designed to be a strong baseline for product teams that want a clean, repeatable Flutter structure without starting from a single-screen demo app.
app/bootstrap.dartHandles app startup and environment loading.app/app.dartBuilds the rootMaterialApp.router.app/router/app_router.dartDefines top-level routes and shell navigation.app/shell/app_shell.dartHosts the bottom navigation shell for multi-feature apps.
core/configApp config and environment parsing.core/errorsShared failure and result types.core/networkDio client creation and connectivity abstraction.core/themeCentralized app theming.
dashboardProduct-style landing screen for the starter kit.authDemo auth flow with repository contracts and use cases.postsFull reference feature with domain, repository contract, remote datasource, local datasource, cache, and UI.settingsApp-wide settings feature with theme preference handling.
shared/widgetsReusable UI building blocks shared across features.
Each feature follows a feature-first clean structure:
features/
some_feature/
data/
datasources/
models/
repositories/
domain/
entities/
repositories/
usecases/
presentation/
providers/
screens/
widgets/
Rules:
presentationtalks to providers and use casesdomainowns business entities and contractsdataimplements repositories and handles API/cache/db detailscorecontains only app-wide shared infrastructure- feature-specific code stays inside its own feature
lib/
app/
app.dart
bootstrap.dart
router/
app_router.dart
shell/
app_shell.dart
core/
config/
errors/
network/
providers/
theme/
features/
auth/
data/
domain/
presentation/
dashboard/
presentation/
posts/
data/
domain/
presentation/
settings/
data/
domain/
presentation/
shared/
widgets/
Use the posts feature as the main example when building new modules. It shows:
- repository contract in domain
- repository implementation in data
- use case orchestration
- remote API loading with Dio
- local cache with Drift
- connectivity-aware fallback logic
- UI feedback for live vs cached data
The auth feature is currently demo-backed with an in-memory repository, but the structure is ready for:
- API auth
- token persistence
- secure storage
- session refresh
- role-based routing
The settings feature is the place for app-level preferences such as:
- theme mode
- language
- onboarding flags
- notification preferences
- remote config toggles
The starter currently includes:
DashboardPostsSettingsAccount
Dashboard, Posts, and Settings live inside the shell navigation. Account is routed separately.
This project expects a .env file with:
BASE_URL=https://your-api-base-url.comBASE_URL is required for the Dio client.
flutter pub getThis starter uses Drift code generation.
dart run build_runner buildflutter runRun these before pushing changes:
flutter analyze
flutter testWhen adding a new feature like orders, notifications, or reports:
- Create
data,domain, andpresentationfolders insidelib/features/<feature_name>/. - Add domain entities, repository contracts, and use cases first.
- Implement repositories and datasources in
data/. - Add Riverpod providers in
presentation/providers/. - Add screens/widgets in
presentation/. - Register the feature in
app/router/app_router.dartif it needs navigation.
If you want to grow this starter further, good next upgrades are:
- Add persistent auth with secure storage.
- Add API interceptors for auth tokens and retry handling.
- Add flavors for
dev,staging, andprod. - Add localization support.
- Split large apps into
packages/when multiple teams/features grow independently.
This starter is a good fit for:
- startup apps that want clean foundations
- product teams building multiple modules
- internal enterprise apps
- Flutter apps that need both API and local cache support
It is intentionally not overengineered into full multi-package modularization yet, so teams can move quickly first and split later when the app grows.