Keyboard Shortcuts

j / kScroll down / up
ggScroll to top
GScroll to bottom
K / /Open search
?Show this help
EscClose search / help
n / NNext / previous section
hGo to landing
dGo to docs
:Command mode — type section name

Press ? or Esc to close

Getting Started

Project Structure

Two top-level concerns: config/ for global services, features/ for everything product-specific. Everything has one obvious home.

main.dart # Entry point
firebase_options.dart # Firebase auto-generated config
app/
app_bootstrap.dart # DI setup, Firebase init, service registration
app.dart # Root widget, MultiBlocProvider, MaterialApp.router
app_router.dart # GoRouter config, StatefulShellRoute, auth guard
app_routes.dart # Route enum definitions
config/
constants/ # AppConstants, AppIcons, AppImages, StorageKeys
database/ # Sqflite with migration system
localization/ # 3-source localization + TranslationKeys enum
logging/ # Logger initialization
network/ # ApiClient, interceptors, BaseStore, ApiResponse
theme/ # AppColors, AppThemeColors, AppTypography, AppSpacing
ui/ # 30+ reusable widgets
utils/ # Services: analytics, crashlytics, deep_link, etc.
features/
<feature>/
config/ # DI registration + route definition (public API)
data/ # models, source, store, local (cache)
logic/ # Cubit + State (or Bloc + Event)
presentation/ # screens + widgets

app/ — Composition Only

No business logic. Only global/core services registered here: ApiClient, AppDatabase, ThemeCubit, LocalizationCubit, GlobalErrorCubit. Feature DI is NOT registered here.

config/ — Global Services

Stateless, globally available, has zero feature imports. All third-party service wrappers live here. Add database/ only if offline support is needed.

features/{name}/config/ — Feature Public API

Route defined here, registered in app_router.dart. The feature's DI module (registerXxxDependencies()) is called once at bootstrap. This is the only public API of the feature — nothing else is imported from outside.

sam's arch — A Pragmatic Flutter Architecture