Modes & architecture
Mode is the single most important choice in Flutter Launchpad. It picks the whole convention stack — architecture, state management, navigation, storage, and the house rules the generated code follows. There are three:
structured-getx— opinionated GetX with ageneral_exportsmega-barrel.structured-riverpod— rawflutter_riverpod+ GoRouter, same barrel.generic— vanilla Flutter; you choose the state library, navigation, and folders.
Structured vs generic
Section titled “Structured vs generic”The two structured modes are opinionated: they encode a strict set of
conventions and derive State management, Architecture, and Navigation from the
mode itself. Those three fields are locked in the UI — they have no effect
because the generators read them from mode.
| Structured mode | State | Architecture | Navigation | Storage |
|---|---|---|---|---|
structured-getx | GetX | feature folders | named routes | get_storage |
structured-riverpod | Riverpod | feature folders | GoRouter | shared_preferences |
Generic mode enforces nothing. State management, navigation, and architecture
are all yours to pick, and no general_exports barrel or ScreenUtil sizing is
imposed.
Some things are the same in every mode: the typed API envelope
(ApiResponse<T> / PaginatedResponse<T> / ApiError), your selected models,
and the optional Professional base layer (DI + Dio client + Result/Failure +
base repository/usecase + network_info) — which clean architecture always
pulls in.
The structured house rules
Section titled “The structured house rules”Both structured modes share the same non-negotiable conventions:
- One mega-barrel. Every file imports only
package:<app>/general_exports.dart, which re-exports Flutter, the state library,flutter_screenutil, and every subtreeindex.dart. - One API client. All networking goes through a single hand-rolled
ApiRequest(wrapping Dio) — no retrofit, no codegen. Endpoints areApiEndpointsconstants; every JSON/storage key is anAppKeysconstant. - Feature folders. One folder per feature under
lib/screens/<feature>/with a screen, a controller, and a barrel. - Side-effect free-functions. Screens never call
print, a dialog, or a plugin directly — they callconsoleLog/startLoading/showMessage. - ≤150 lines per file, strict lints,
flutter_smart_dialogfor global loading/toast, andflutter_screenutilsizing on a 390×844 canvas.
structured-getx
Section titled “structured-getx”The opinionated GetX stack.
- State:
GetxControllerfield bags; mutate fields then callupdate(). Screens areStatelessWidgets wrapped inGetBuilder— noObxstate objects required. - Navigation: GetX named routes. Route constants live in
routes_keys.dart; aGetPagelist inroutes.dartmaps them to screens. Never hardcode a route string. - Root:
GetMaterialAppinsideScreenUtilInit, withSmartDialoginit in the builder. Cross-screen singletons areGet.putonce inmy_app.dart. - Storage:
get_storage, wrapped inLocalStorage. - Localization: GetX native translations — strings in
AppTranslations, resolved withTranslationKeys.x.tr; locale switched viaLocaleController.
structured-riverpod
Section titled “structured-riverpod”The same conventions on a Riverpod foundation — deliberately codegen-free.
- State: raw
flutter_riverpodNotifiers with mutable field bags andref.notifyListeners(). No@riverpodcodegen and no freezed for state. Screens areConsumerWidgets. Ships withcustom_lint+riverpod_lintas dev dependencies. - Navigation: GoRouter via a
routerProvider, withroute*path constants. Screen arguments pass through a globalglobalArgumentsmap. - Storage:
shared_preferences, wrapped inLocalStorage. - Localization: Flutter
gen-l10n. Strings live inlib/l10n/app_*.arb; runningflutter gen-l10nemitsAppLocalizations. Locale is switched and persisted through a provider. Requiresflutter gen-l10n(or apub getwithgenerate: true) before the first build.
generic
Section titled “generic”Vanilla Flutter — the plain-Flutter idiom, no structured house rules.
- State management is free:
getx,riverpod,bloc,provider, ornone. The capability layer uses plainChangeNotifier/ValueNotifierand does not impose a barrel orScreenUtil. - Architecture is meaningful here:
clean— full Clean Architecture:data → domain → presentationwith a repository + usecase + entity and a working sample feature wired end to end. Pulls in the Professional base layer automatically.mvc— Model / View / Controller; aChangeNotifiercontroller drives the view, with a real sample.mvvm— Model / View / ViewModel; the view binds to aChangeNotifierViewModel, with a real sample.layer-folder—core/data/domain/presentationfolders with.gitkeepplaceholders for you to fill.
- Every capability toggle still emits a real, buildable file (services,
widgets, theme, i18n, env, permissions). What’s left to you is the root
wiring —
app.dart/main.dartcomposition — so you can plug the generated pieces into your own state and navigation setup.
Choosing a mode
Section titled “Choosing a mode”- Want the fastest path with the most conventions decided for you, and you like
GetX? →
structured-getx. - Prefer Riverpod + GoRouter, still fully opinionated and codegen-free? →
structured-riverpod. - Want to keep control of state, navigation, and folder layout, or you’re dropping
the scaffold into an existing style? →
generic(withclean/mvc/mvvmif you want a wired sample to copy).