Generated conventions
Every project Flutter Launchpad generates follows a consistent shape. This page describes what you actually get on disk so you know where each thing lives and how the pieces connect. The examples use a structured project; the modes page covers how generic mode differs.
Folder layout (structured)
Section titled “Folder layout (structured)”lib/ general_exports.dart # the single mega-barrel — import ONLY this main.dart # entrypoint: bindings, storage init, runApp api/ index.dart api_request.dart # the one Dio wrapper api_endpoints.dart # ApiEndpoints path constants app_keys.dart # AppKeys — every JSON/storage key translation_keys.dart # TranslationKeys — i18n message keys theme/ app_colors.dart # AppColors palette app_theme.dart # light/dark Material 3 themes theme_controller.dart # runtime toggle + persistence (when dark) constants/ app_constants.dart app_assets.dart # AppAssets — asset path constants app_info.dart # name/version/base URL general_constants.dart # AppMode + currentMode (when flavors) utils/ local_storage.dart # LocalStorage keyed by AppKeys helper/log.dart # consoleLog helper/global_functions.dart # startLoading / stopLoading / showMessage components/ # shared App* widgets screens/ my_app/ # root widget + routes + routes_keys <feature>/ # screen + controller + barrel, one per feature core/network/ # ApiResponse / PaginatedResponse / ApiError models/ # your typed models (when any) services/ # gated capability servicesassets/ images/ svg/ fonts/ icon/ splash/ # .gitkeep placeholdersAlongside lib/ you get pubspec.yaml, analysis_options.yaml, the docs
(README.md, SETUP.md, PACKAGES.md, CLAUDE.md, AGENTS.md, MANIFEST.md,
docs/features/), and repo hygiene (.gitignore, .editorconfig,
.vscode/launch.json, .githooks/pre-commit, .github/workflows/ci.yml).
The mega-barrel
Section titled “The mega-barrel”lib/general_exports.dart is the single import. It re-exports Flutter, the state
library (get or flutter_riverpod), flutter_screenutil, and every subtree
index.dart. Every file imports only this:
import 'package:my_app/general_exports.dart';API layer
Section titled “API layer”All networking flows through one hand-rolled ApiRequest (wrapping Dio) — no
retrofit, no codegen. It auto-injects the bearer token and Accept-Language, logs
the call, and surfaces errors via showMessage unless you opt out. Two rules keep
it clean:
- Endpoints are constants on
ApiEndpoints— never inline a URL string. The base URL is chosen percurrentModewhen flavors are on. - Keys are constants on
AppKeys— every JSON request/response and storage key. Never a raw string key.
Models & the network envelope
Section titled “Models & the network envelope”Every mode emits the typed envelope under lib/core/network/:
ApiResponse<T>, PaginatedResponse<T>, and ApiError. Your own models land in
lib/models/ with a barrel. The API models setting decides how they’re
written:
- Manual — plain Dart with hand-written
fromJson/toJson, nobuild_runner. - freezed — immutable
@freezedclasses withjson_serializable(addsbuild_runner).
Models are parsed defensively (type-check + tryParse + sane defaults + a static
listFrom), per the generated rules.
Theming
Section titled “Theming”AppColorsholds the palette; reference colors only through it.app_theme.dartbuilds Material 3 light/dark themes seeded fromAppColors.- When dark is enabled,
ThemeControllerswitches and persists the theme mode (viaGet.changeThemeModein GetX, or athemeModeProviderin Riverpod). - Selecting dynamic adds
flex_color_scheme. - Sizing uses
flutter_screenutilon a 390×844 canvas — size with.w/.h/.sp/.r, never raw pixels.
Design tokens (AppSpacing, text styles) and validators come in via the UI kit
when the matching components are selected.
Features
Section titled “Features”Each feature is a folder under lib/screens/<feature>/ with a screen, a
controller, and a barrel — one real, wired sample per feature:
- GetX — a
GetxControllerfield bag; mutate fields thenupdate(). Screens areStatelessWidgets in aGetBuilder. - Riverpod — a raw
Notifier+ in-file provider; mutate fields thenref.notifyListeners(). Screens areConsumerWidgets.
A controller’s HTTP calls belong in a sibling <feature>_requests.dart so both
stay under 150 lines. When the test scaffold is on, each feature also gets a
test/<feature>_controller_test.dart (using mocktail) and a doc under
docs/features/.
Services
Section titled “Services”Capability code lives in lib/services/ and is called only from controllers —
never a plugin dropped into a screen. What’s generated depends on your toggles:
| Service | Enabled by |
|---|---|
ConnectivityService | Connectivity selection |
NotificationService | Notifications → local (per-flavor channel; big-picture when rich) |
PushNotificationService | Notifications → push (token cache, cold-start + tap deep links) |
DeepLinkService | Notifications → deep links (app_links) |
FirebaseService | Firebase → analytics/crashlytics |
LocationService / AddressService | Maps → geolocator / geocoding |
SecureStorage | Security → secure storage |
LinkService | URL launcher |
MaintenanceService | Maintenance gate |
PermissionService | Any permission (or consent) |
Firebase
Section titled “Firebase”Firebase toggles add the products, a firebase_options.dart placeholder, a
FirebaseService (when analytics/crashlytics are on), and a FIREBASE.md. You
supply the real config with flutterfire configure (or by renaming the *.example
files). Initialize Firebase in main() before runApp.
Localization
Section titled “Localization”- structured-getx — GetX native translations: strings in
AppTranslations(lib/utils/app_translations.dart), resolved withTranslationKeys.x.tr; locale switched and persisted viaLocaleController. Shipsen+ar(RTL). - structured-riverpod / generic — Flutter
gen-l10n: strings inlib/l10n/app_*.arb, a globall10naccessor, anl10n.yaml, andgenerate: trueinpubspec.yaml. Runflutter gen-l10nto (re)buildAppLocalizations.
Flavors & environments
Section titled “Flavors & environments”The structured convention is a compile-time environment. general_constants.dart
defines an AppMode enum and a currentMode; the API base URL is selected per
mode in api_endpoints.dart. Switch environments by editing currentMode — no
native flavors required.
Turn on Native flavors to also get real Android productFlavors, per-flavor
entry points (lib/main_<flavor>.dart), matching .vscode/launch.json configs,
and a FLAVORS.md with iOS + per-flavor Firebase/icon steps.
Storage & logging
Section titled “Storage & logging”LocalStoragewrapsget_storage(GetX) orshared_preferences(Riverpod), keyed byAppKeysconstants. Tokens and PII belong in secure storage, not here.consoleLogis the only logging call (avoid_printis enforced). Adding file logging also writes everyconsoleLogto an on-device log file;loggerandpretty_dio_loggerare optional richer loggers.
Permissions
Section titled “Permissions”Selecting permissions generates a request<Name>() method per permission plus the
Android <uses-permission> entries and iOS usage strings, collected in
MANIFEST.md (and platform/ files in generic mode). Paste them into your native
config; request permissions at point-of-use, and handle denied /
permanently-denied.
Docs & AI rules
Section titled “Docs & AI rules”Every project ships CLAUDE.md and AGENTS.md seeded with the conventions above
plus your selected rule presets, so a coding agent extends the project in-style
instead of guessing. SETUP.md is a bring-up checklist scoped to your exact
config, PACKAGES.md explains why each dependency is there, and docs/features/
holds one doc per feature plus capability docs (theming, i18n, notifications,
maintenance).