Repository files navigation

Stacked Plus

A Flutter starter project built on Stacked. It includes the base architecture, routing, dependency injection, startup logic, Firebase hooks, analytics, localization, shared preferences, connectivity handling, flavors, linting, tests, and development scripts needed to start a production app with less setup work.

For the project-specific startup flow, read docs/stacked-startup-logic.md.

Quick Start

Use this path when setting up the project for the first time.

# 1. Check Flutter is available
flutter --version
flutter doctor
# 2. Install FVM if it is not already installed
dart pub global activate fvm
# 3. Install the Flutter SDK version from .fvmrc
fvm install
# 4. Install Melos if it is not already installed
dart pub global activate melos
# 5. Install dependencies and Git hooks
melos run init
# 6. Generate localization, routes, locator, mocks, and other generated code
melos run generate
# 7. Run analyzer and tests
melos run analyze
melos run test

If dart is not recognized on Windows, add the Flutter SDK bin directory to your PATH, then restart the terminal. The Flutter SDK provides both flutter and dart.

As a temporary fallback, use Flutter commands directly:

flutter pub get
flutter pub global activate fvm
flutter pub global activate melos

Running The App

This project has three flavor entrypoints:

EnvironmentDart entrypointNative flavorMelos command
Testlib/main_test.dartfortestmelos run run:test
Developmentlib/main_dev.dartdevelopmentmelos run run:dev
Productionlib/main_prod.dartproductionmelos run run:prod

Equivalent raw Flutter commands:

fvm flutter run -t lib/main_test.dart --flavor fortest
fvm flutter run -t lib/main_dev.dart --flavor development
fvm flutter run -t lib/main_prod.dart --flavor production

For web:

melos run web-run:test
melos run web-run:dev
melos run web-run:prod

Firebase Setup

Firebase is initialized in lib/app/setup_firebase.dart.

On mobile, Firebase.initializeApp() uses native Firebase config files:

PlatformConfig file
Android testandroid/app/src/fortest/google-services.json
Android developmentandroid/app/src/development/google-services.json
Android productionandroid/app/src/production/google-services.json
iOSAdd the matching GoogleService-Info.plist to the Runner target/scheme

The Android application IDs are configured in android/app/build.gradle.kts:

FlavorApplication ID
productioncom.example.flutter_base
developmentcom.example.flutter_base.dev
fortestcom.example.flutter_base.test

On web, Firebase requires explicit FirebaseOptions. This project reads them from Dart defines in lib/app/firebase_config.dart.

fvm flutter run -d chrome -t lib/main_test.dart `--dart-define=FIREBASE_API_KEY=your-api-key `--dart-define=FIREBASE_APP_ID=your-app-id `--dart-define=FIREBASE_MESSAGING_SENDER_ID=your-sender-id `--dart-define=FIREBASE_PROJECT_ID=your-project-id `--dart-define=FIREBASE_AUTH_DOMAIN=your-project.firebaseapp.com`--dart-define=FIREBASE_STORAGE_BUCKET=your-project.appspot.com`--dart-define=FIREBASE_MEASUREMENT_ID=your-measurement-id

If the required web values are missing, the app skips Firebase on web and disables Firebase Analytics for that run. This prevents:

FirebaseOptions cannot be null when creating the default app.

Project Structure

PathPurpose
lib/main.dartShared app boot sequence used by all flavors
lib/main_dev.dartDevelopment flavor entrypoint
lib/main_test.dartTest flavor entrypoint
lib/main_prod.dartProduction flavor entrypoint
lib/app/app.dartStacked annotations for routes, services, dialogs, and sheets
lib/app/app.locator.dartGenerated service locator
lib/app/app.router.dartGenerated router
lib/app/app.dialogs.dartGenerated dialog setup
lib/app/app.bottomsheets.dartGenerated bottom sheet setup
lib/ui/viewsScreens and ViewModels
lib/ui/commonShared UI helpers and base widgets
lib/servicesApp services registered with Stacked
lib/l10nARB localization source files
lib/generatedGenerated localization output
test/helpersTest service registration and generated mocks
docsProject-specific documentation

Generated files should not be edited by hand. Update the source annotations or ARB files, then regenerate.

Stacked Workflow

Use lib/app/app.dart as the source of truth for Stacked setup.

When adding a new route, service, dialog, or bottom sheet:

  1. Add the class in the correct project folder.
  2. Register it in lib/app/app.dart.
  3. Run code generation.
melos run generate

The same command runs:

fvm dart run intl_utils:generate
fvm dart run build_runner build --delete-conflicting-outputs

If you use the Stacked CLI:

dart pub global activate stacked_cli
stacked create view login
stacked create service authentication
melos run generate

Startup Flow

Boot order:

  1. main_dev.dart, main_test.dart, or main_prod.dart sets FlavorConfig.
  2. mainApp() in lib/main.dart initializes Flutter bindings.
  3. Stacked locator, dialogs, and bottom sheets are set up.
  4. ConnectivityService starts listening for connectivity changes.
  5. Firebase is initialized when config is available.
  6. AnalyticsService creates enabled integrations.
  7. MaterialApp starts at Routes.startupView.
  8. StartupViewModel.runStartupLogic() performs app startup decisions.
  9. Navigation replaces startup with HomeView.

Keep infrastructure setup in mainApp(). Put user-facing startup decisions, such as auth checks, onboarding checks, cached settings, or redirect logic, in StartupViewModel.runStartupLogic().

Services

Services are registered in lib/app/app.dart and accessed through the Stacked locator.

final preferences =locator<SharedPreferencesService>();
await preferences.put('themeMode', 'dark');
final themeMode =await preferences.getString('themeMode');

Available project services:

ServiceFilePurpose
AnalyticsServicelib/services/analytics/analytics_service.dartAnalytics abstraction with Firebase adapter support
ConnectivityServicelib/services/connectivity/connectivity_service.dartTracks online/offline state
SharedPreferencesServicelib/services/shared_preferences/shared_preferences_service.dartTyped wrapper around shared_preferences
FeatureFlaglib/common/feature_flags.dartEnvironment-aware feature flags

DgBaseView in lib/ui/common/base_view.dart uses ConnectivityService to show a no-internet banner by default. Disable it per screen when needed:

DgBaseView(
showConnectivityBanner:false,
child:YourContent(),
);

Localization

Source strings live in lib/l10n/*.arb.

After editing ARB files, regenerate:

melos run strings

The generated localization class is imported as:

import'package:flutter_base/generated/l10n.dart';

Quality Checks

Run these before opening a pull request or sharing the project:

fvm dart format lib test
melos run analyze
melos run test
melos run test:golden

Update golden files only when the UI change is intentional:

melos run update:golden

The analyzer configuration is in analysis_options.yaml and uses total_lints.

Useful Commands

CommandPurpose
melos run initInstall dependencies and Git hooks
melos run generateGenerate localization and Stacked code
melos run stringsGenerate localization only
melos run analyzeRun Flutter analyzer
melos run testRun unit and widget tests
melos run test:goldenRun golden tests
melos run update:goldenUpdate golden snapshots
melos run clear-cacheClean build runner cache
melos run generate-launcher-iconGenerate launcher icons

Common Troubleshooting

dart is not recognized

Add Flutter's bin directory to the Windows PATH. Check with:

where flutter
where dart

If flutter works but dart does not, restart the terminal after updating PATH, or use flutter pub ... commands temporarily.

Firebase Web Options Are Missing

Use the Dart defines shown in the Firebase section. Without them, Firebase is skipped on web by design.

Generated Files Are Out Of Date

Run:

melos run generate

This fixes most missing route, locator, mock, and localization outputs.

Build Runner Has Conflicts

Run:

melos run clear-cache
melos run generate

Included Libraries

AreaLibraries
Architecturestacked, stacked_services, stacked_generator
Firebasefirebase_core, firebase_analytics, firebase_crashlytics
Environmentsflutter_flavor, device_preview
Datahive, hive_flutter, shared_preferences
Connectivityconnectivity_plus
Localizationintl, intl_utils, flutter_localizations
Models and codegenfreezed, freezed_annotation, build_runner
Testingflutter_test, mockito, golden_toolkit, network_image_mock
Workflowfvm, melos, husky, total_lints, flutter_launcher_icons

Before Building A Real App

Update these project defaults:

  1. Rename the app package in pubspec.yaml if flutter_base is not the final package name.
  2. Update Android namespace and applicationId in android/app/build.gradle.kts.
  3. Update iOS bundle IDs in Xcode.
  4. Replace Firebase config files for each flavor.
  5. Replace launcher icons in assets/images and regenerate icons.
  6. Review feature flags in lib/common/feature_flags.dart.

About

Production-ready Flutter boilerplate built on the Stacked framework with essential tools preconfigured—Melos, FVM, Husky, Firebase, localization, linting, state management, database, and more—so you can skip setup and start building scalable, maintainable apps instantly.

Topics

Resources

Stars

2 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Repository files navigation

Stacked Plus

A Flutter starter project built on Stacked. It includes the base architecture, routing, dependency injection, startup logic, Firebase hooks, analytics, localization, shared preferences, connectivity handling, flavors, linting, tests, and development scripts needed to start a production app with less setup work.

For the project-specific startup flow, read docs/stacked-startup-logic.md.

Quick Start

Use this path when setting up the project for the first time.

# 1. Check Flutter is available
flutter --version
flutter doctor
# 2. Install FVM if it is not already installed
dart pub global activate fvm
# 3. Install the Flutter SDK version from .fvmrc
fvm install
# 4. Install Melos if it is not already installed
dart pub global activate melos
# 5. Install dependencies and Git hooks
melos run init
# 6. Generate localization, routes, locator, mocks, and other generated code
melos run generate
# 7. Run analyzer and tests
melos run analyze
melos run test

If dart is not recognized on Windows, add the Flutter SDK bin directory to your PATH, then restart the terminal. The Flutter SDK provides both flutter and dart.

As a temporary fallback, use Flutter commands directly:

flutter pub get
flutter pub global activate fvm
flutter pub global activate melos

Running The App

This project has three flavor entrypoints:

EnvironmentDart entrypointNative flavorMelos command
Testlib/main_test.dartfortestmelos run run:test
Developmentlib/main_dev.dartdevelopmentmelos run run:dev
Productionlib/main_prod.dartproductionmelos run run:prod

Equivalent raw Flutter commands:

fvm flutter run -t lib/main_test.dart --flavor fortest
fvm flutter run -t lib/main_dev.dart --flavor development
fvm flutter run -t lib/main_prod.dart --flavor production

For web:

melos run web-run:test
melos run web-run:dev
melos run web-run:prod

Firebase Setup

Firebase is initialized in lib/app/setup_firebase.dart.

On mobile, Firebase.initializeApp() uses native Firebase config files:

PlatformConfig file
Android testandroid/app/src/fortest/google-services.json
Android developmentandroid/app/src/development/google-services.json
Android productionandroid/app/src/production/google-services.json
iOSAdd the matching GoogleService-Info.plist to the Runner target/scheme

The Android application IDs are configured in android/app/build.gradle.kts:

FlavorApplication ID
productioncom.example.flutter_base
developmentcom.example.flutter_base.dev
fortestcom.example.flutter_base.test

On web, Firebase requires explicit FirebaseOptions. This project reads them from Dart defines in lib/app/firebase_config.dart.

fvm flutter run -d chrome -t lib/main_test.dart `--dart-define=FIREBASE_API_KEY=your-api-key `--dart-define=FIREBASE_APP_ID=your-app-id `--dart-define=FIREBASE_MESSAGING_SENDER_ID=your-sender-id `--dart-define=FIREBASE_PROJECT_ID=your-project-id `--dart-define=FIREBASE_AUTH_DOMAIN=your-project.firebaseapp.com`--dart-define=FIREBASE_STORAGE_BUCKET=your-project.appspot.com`--dart-define=FIREBASE_MEASUREMENT_ID=your-measurement-id

If the required web values are missing, the app skips Firebase on web and disables Firebase Analytics for that run. This prevents:

FirebaseOptions cannot be null when creating the default app.

Project Structure

PathPurpose
lib/main.dartShared app boot sequence used by all flavors
lib/main_dev.dartDevelopment flavor entrypoint
lib/main_test.dartTest flavor entrypoint
lib/main_prod.dartProduction flavor entrypoint
lib/app/app.dartStacked annotations for routes, services, dialogs, and sheets
lib/app/app.locator.dartGenerated service locator
lib/app/app.router.dartGenerated router
lib/app/app.dialogs.dartGenerated dialog setup
lib/app/app.bottomsheets.dartGenerated bottom sheet setup
lib/ui/viewsScreens and ViewModels
lib/ui/commonShared UI helpers and base widgets
lib/servicesApp services registered with Stacked
lib/l10nARB localization source files
lib/generatedGenerated localization output
test/helpersTest service registration and generated mocks
docsProject-specific documentation

Generated files should not be edited by hand. Update the source annotations or ARB files, then regenerate.

Stacked Workflow

Use lib/app/app.dart as the source of truth for Stacked setup.

When adding a new route, service, dialog, or bottom sheet:

  1. Add the class in the correct project folder.
  2. Register it in lib/app/app.dart.
  3. Run code generation.
melos run generate

The same command runs:

fvm dart run intl_utils:generate
fvm dart run build_runner build --delete-conflicting-outputs

If you use the Stacked CLI:

dart pub global activate stacked_cli
stacked create view login
stacked create service authentication
melos run generate

Startup Flow

Boot order:

  1. main_dev.dart, main_test.dart, or main_prod.dart sets FlavorConfig.
  2. mainApp() in lib/main.dart initializes Flutter bindings.
  3. Stacked locator, dialogs, and bottom sheets are set up.
  4. ConnectivityService starts listening for connectivity changes.
  5. Firebase is initialized when config is available.
  6. AnalyticsService creates enabled integrations.
  7. MaterialApp starts at Routes.startupView.
  8. StartupViewModel.runStartupLogic() performs app startup decisions.
  9. Navigation replaces startup with HomeView.

Keep infrastructure setup in mainApp(). Put user-facing startup decisions, such as auth checks, onboarding checks, cached settings, or redirect logic, in StartupViewModel.runStartupLogic().

Services

Services are registered in lib/app/app.dart and accessed through the Stacked locator.

final preferences =locator<SharedPreferencesService>();
await preferences.put('themeMode', 'dark');
final themeMode =await preferences.getString('themeMode');

Available project services:

ServiceFilePurpose
AnalyticsServicelib/services/analytics/analytics_service.dartAnalytics abstraction with Firebase adapter support
ConnectivityServicelib/services/connectivity/connectivity_service.dartTracks online/offline state
SharedPreferencesServicelib/services/shared_preferences/shared_preferences_service.dartTyped wrapper around shared_preferences
FeatureFlaglib/common/feature_flags.dartEnvironment-aware feature flags

DgBaseView in lib/ui/common/base_view.dart uses ConnectivityService to show a no-internet banner by default. Disable it per screen when needed:

DgBaseView(
showConnectivityBanner:false,
child:YourContent(),
);

Localization

Source strings live in lib/l10n/*.arb.

After editing ARB files, regenerate:

melos run strings

The generated localization class is imported as:

import'package:flutter_base/generated/l10n.dart';

Quality Checks

Run these before opening a pull request or sharing the project:

fvm dart format lib test
melos run analyze
melos run test
melos run test:golden

Update golden files only when the UI change is intentional:

melos run update:golden

The analyzer configuration is in analysis_options.yaml and uses total_lints.

Useful Commands

CommandPurpose
melos run initInstall dependencies and Git hooks
melos run generateGenerate localization and Stacked code
melos run stringsGenerate localization only
melos run analyzeRun Flutter analyzer
melos run testRun unit and widget tests
melos run test:goldenRun golden tests
melos run update:goldenUpdate golden snapshots
melos run clear-cacheClean build runner cache
melos run generate-launcher-iconGenerate launcher icons

Common Troubleshooting

dart is not recognized

Add Flutter's bin directory to the Windows PATH. Check with:

where flutter
where dart

If flutter works but dart does not, restart the terminal after updating PATH, or use flutter pub ... commands temporarily.

Firebase Web Options Are Missing

Use the Dart defines shown in the Firebase section. Without them, Firebase is skipped on web by design.

Generated Files Are Out Of Date

Run:

melos run generate

This fixes most missing route, locator, mock, and localization outputs.

Build Runner Has Conflicts

Run:

melos run clear-cache
melos run generate

Included Libraries

AreaLibraries
Architecturestacked, stacked_services, stacked_generator
Firebasefirebase_core, firebase_analytics, firebase_crashlytics
Environmentsflutter_flavor, device_preview
Datahive, hive_flutter, shared_preferences
Connectivityconnectivity_plus
Localizationintl, intl_utils, flutter_localizations
Models and codegenfreezed, freezed_annotation, build_runner
Testingflutter_test, mockito, golden_toolkit, network_image_mock
Workflowfvm, melos, husky, total_lints, flutter_launcher_icons

Before Building A Real App

Update these project defaults:

  1. Rename the app package in pubspec.yaml if flutter_base is not the final package name.
  2. Update Android namespace and applicationId in android/app/build.gradle.kts.
  3. Update iOS bundle IDs in Xcode.
  4. Replace Firebase config files for each flavor.
  5. Replace launcher icons in assets/images and regenerate icons.
  6. Review feature flags in lib/common/feature_flags.dart.

About

Production-ready Flutter boilerplate built on the Stacked framework with essential tools preconfigured—Melos, FVM, Husky, Firebase, localization, linting, state management, database, and more—so you can skip setup and start building scalable, maintainable apps instantly.

Topics

Resources

Stars

2 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

Stacked Plus

A Flutter starter project built on Stacked. It includes the base architecture, routing, dependency injection, startup logic, Firebase hooks, analytics, localization, shared preferences, connectivity handling, flavors, linting, tests, and development scripts needed to start a production app with less setup work.

For the project-specific startup flow, read docs/stacked-startup-logic.md.

Quick Start

Use this path when setting up the project for the first time.

# 1. Check Flutter is available
flutter --version
flutter doctor
# 2. Install FVM if it is not already installed
dart pub global activate fvm
# 3. Install the Flutter SDK version from .fvmrc
fvm install
# 4. Install Melos if it is not already installed
dart pub global activate melos
# 5. Install dependencies and Git hooks
melos run init
# 6. Generate localization, routes, locator, mocks, and other generated code
melos run generate
# 7. Run analyzer and tests
melos run analyze
melos run test

If dart is not recognized on Windows, add the Flutter SDK bin directory to your PATH, then restart the terminal. The Flutter SDK provides both flutter and dart.

As a temporary fallback, use Flutter commands directly:

flutter pub get
flutter pub global activate fvm
flutter pub global activate melos

Running The App

This project has three flavor entrypoints:

EnvironmentDart entrypointNative flavorMelos command
Testlib/main_test.dartfortestmelos run run:test
Developmentlib/main_dev.dartdevelopmentmelos run run:dev
Productionlib/main_prod.dartproductionmelos run run:prod

Equivalent raw Flutter commands:

fvm flutter run -t lib/main_test.dart --flavor fortest
fvm flutter run -t lib/main_dev.dart --flavor development
fvm flutter run -t lib/main_prod.dart --flavor production

For web:

melos run web-run:test
melos run web-run:dev
melos run web-run:prod

Firebase Setup

Firebase is initialized in lib/app/setup_firebase.dart.

On mobile, Firebase.initializeApp() uses native Firebase config files:

PlatformConfig file
Android testandroid/app/src/fortest/google-services.json
Android developmentandroid/app/src/development/google-services.json
Android productionandroid/app/src/production/google-services.json
iOSAdd the matching GoogleService-Info.plist to the Runner target/scheme

The Android application IDs are configured in android/app/build.gradle.kts:

FlavorApplication ID
productioncom.example.flutter_base
developmentcom.example.flutter_base.dev
fortestcom.example.flutter_base.test

On web, Firebase requires explicit FirebaseOptions. This project reads them from Dart defines in lib/app/firebase_config.dart.

fvm flutter run -d chrome -t lib/main_test.dart `--dart-define=FIREBASE_API_KEY=your-api-key `--dart-define=FIREBASE_APP_ID=your-app-id `--dart-define=FIREBASE_MESSAGING_SENDER_ID=your-sender-id `--dart-define=FIREBASE_PROJECT_ID=your-project-id `--dart-define=FIREBASE_AUTH_DOMAIN=your-project.firebaseapp.com`--dart-define=FIREBASE_STORAGE_BUCKET=your-project.appspot.com`--dart-define=FIREBASE_MEASUREMENT_ID=your-measurement-id

If the required web values are missing, the app skips Firebase on web and disables Firebase Analytics for that run. This prevents:

FirebaseOptions cannot be null when creating the default app.

Project Structure

PathPurpose
lib/main.dartShared app boot sequence used by all flavors
lib/main_dev.dartDevelopment flavor entrypoint
lib/main_test.dartTest flavor entrypoint
lib/main_prod.dartProduction flavor entrypoint
lib/app/app.dartStacked annotations for routes, services, dialogs, and sheets
lib/app/app.locator.dartGenerated service locator
lib/app/app.router.dartGenerated router
lib/app/app.dialogs.dartGenerated dialog setup
lib/app/app.bottomsheets.dartGenerated bottom sheet setup
lib/ui/viewsScreens and ViewModels
lib/ui/commonShared UI helpers and base widgets
lib/servicesApp services registered with Stacked
lib/l10nARB localization source files
lib/generatedGenerated localization output
test/helpersTest service registration and generated mocks
docsProject-specific documentation

Generated files should not be edited by hand. Update the source annotations or ARB files, then regenerate.

Stacked Workflow

Use lib/app/app.dart as the source of truth for Stacked setup.

When adding a new route, service, dialog, or bottom sheet:

  1. Add the class in the correct project folder.
  2. Register it in lib/app/app.dart.
  3. Run code generation.
melos run generate

The same command runs:

fvm dart run intl_utils:generate
fvm dart run build_runner build --delete-conflicting-outputs

If you use the Stacked CLI:

dart pub global activate stacked_cli
stacked create view login
stacked create service authentication
melos run generate

Startup Flow

Boot order:

  1. main_dev.dart, main_test.dart, or main_prod.dart sets FlavorConfig.
  2. mainApp() in lib/main.dart initializes Flutter bindings.
  3. Stacked locator, dialogs, and bottom sheets are set up.
  4. ConnectivityService starts listening for connectivity changes.
  5. Firebase is initialized when config is available.
  6. AnalyticsService creates enabled integrations.
  7. MaterialApp starts at Routes.startupView.
  8. StartupViewModel.runStartupLogic() performs app startup decisions.
  9. Navigation replaces startup with HomeView.

Keep infrastructure setup in mainApp(). Put user-facing startup decisions, such as auth checks, onboarding checks, cached settings, or redirect logic, in StartupViewModel.runStartupLogic().

Services

Services are registered in lib/app/app.dart and accessed through the Stacked locator.

final preferences =locator<SharedPreferencesService>();
await preferences.put('themeMode', 'dark');
final themeMode =await preferences.getString('themeMode');

Available project services:

ServiceFilePurpose
AnalyticsServicelib/services/analytics/analytics_service.dartAnalytics abstraction with Firebase adapter support
ConnectivityServicelib/services/connectivity/connectivity_service.dartTracks online/offline state
SharedPreferencesServicelib/services/shared_preferences/shared_preferences_service.dartTyped wrapper around shared_preferences
FeatureFlaglib/common/feature_flags.dartEnvironment-aware feature flags

DgBaseView in lib/ui/common/base_view.dart uses ConnectivityService to show a no-internet banner by default. Disable it per screen when needed:

DgBaseView(
showConnectivityBanner:false,
child:YourContent(),
);

Localization

Source strings live in lib/l10n/*.arb.

After editing ARB files, regenerate:

melos run strings

The generated localization class is imported as:

import'package:flutter_base/generated/l10n.dart';

Quality Checks

Run these before opening a pull request or sharing the project:

fvm dart format lib test
melos run analyze
melos run test
melos run test:golden

Update golden files only when the UI change is intentional:

melos run update:golden

The analyzer configuration is in analysis_options.yaml and uses total_lints.

Useful Commands

CommandPurpose
melos run initInstall dependencies and Git hooks
melos run generateGenerate localization and Stacked code
melos run stringsGenerate localization only
melos run analyzeRun Flutter analyzer
melos run testRun unit and widget tests
melos run test:goldenRun golden tests
melos run update:goldenUpdate golden snapshots
melos run clear-cacheClean build runner cache
melos run generate-launcher-iconGenerate launcher icons

Common Troubleshooting

dart is not recognized

Add Flutter's bin directory to the Windows PATH. Check with:

where flutter
where dart

If flutter works but dart does not, restart the terminal after updating PATH, or use flutter pub ... commands temporarily.

Firebase Web Options Are Missing

Use the Dart defines shown in the Firebase section. Without them, Firebase is skipped on web by design.

Generated Files Are Out Of Date

Run:

melos run generate

This fixes most missing route, locator, mock, and localization outputs.

Build Runner Has Conflicts

Run:

melos run clear-cache
melos run generate

Included Libraries

AreaLibraries
Architecturestacked, stacked_services, stacked_generator
Firebasefirebase_core, firebase_analytics, firebase_crashlytics
Environmentsflutter_flavor, device_preview
Datahive, hive_flutter, shared_preferences
Connectivityconnectivity_plus
Localizationintl, intl_utils, flutter_localizations
Models and codegenfreezed, freezed_annotation, build_runner
Testingflutter_test, mockito, golden_toolkit, network_image_mock
Workflowfvm, melos, husky, total_lints, flutter_launcher_icons

Before Building A Real App

Update these project defaults:

  1. Rename the app package in pubspec.yaml if flutter_base is not the final package name.
  2. Update Android namespace and applicationId in android/app/build.gradle.kts.
  3. Update iOS bundle IDs in Xcode.
  4. Replace Firebase config files for each flavor.
  5. Replace launcher icons in assets/images and regenerate icons.
  6. Review feature flags in lib/common/feature_flags.dart.

About

Production-ready Flutter boilerplate built on the Stacked framework with essential tools preconfigured—Melos, FVM, Husky, Firebase, localization, linting, state management, database, and more—so you can skip setup and start building scalable, maintainable apps instantly.

Topics

Resources

Stars

2 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

Stacked Plus

A Flutter starter project built on Stacked. It includes the base architecture, routing, dependency injection, startup logic, Firebase hooks, analytics, localization, shared preferences, connectivity handling, flavors, linting, tests, and development scripts needed to start a production app with less setup work.

For the project-specific startup flow, read docs/stacked-startup-logic.md.

Quick Start

Use this path when setting up the project for the first time.

# 1. Check Flutter is available
flutter --version
flutter doctor
# 2. Install FVM if it is not already installed
dart pub global activate fvm
# 3. Install the Flutter SDK version from .fvmrc
fvm install
# 4. Install Melos if it is not already installed
dart pub global activate melos
# 5. Install dependencies and Git hooks
melos run init
# 6. Generate localization, routes, locator, mocks, and other generated code
melos run generate
# 7. Run analyzer and tests
melos run analyze
melos run test

If dart is not recognized on Windows, add the Flutter SDK bin directory to your PATH, then restart the terminal. The Flutter SDK provides both flutter and dart.

As a temporary fallback, use Flutter commands directly:

flutter pub get
flutter pub global activate fvm
flutter pub global activate melos

Running The App

This project has three flavor entrypoints:

EnvironmentDart entrypointNative flavorMelos command
Testlib/main_test.dartfortestmelos run run:test
Developmentlib/main_dev.dartdevelopmentmelos run run:dev
Productionlib/main_prod.dartproductionmelos run run:prod

Equivalent raw Flutter commands:

fvm flutter run -t lib/main_test.dart --flavor fortest
fvm flutter run -t lib/main_dev.dart --flavor development
fvm flutter run -t lib/main_prod.dart --flavor production

For web:

melos run web-run:test
melos run web-run:dev
melos run web-run:prod

Firebase Setup

Firebase is initialized in lib/app/setup_firebase.dart.

On mobile, Firebase.initializeApp() uses native Firebase config files:

PlatformConfig file
Android testandroid/app/src/fortest/google-services.json
Android developmentandroid/app/src/development/google-services.json
Android productionandroid/app/src/production/google-services.json
iOSAdd the matching GoogleService-Info.plist to the Runner target/scheme

The Android application IDs are configured in android/app/build.gradle.kts:

FlavorApplication ID
productioncom.example.flutter_base
developmentcom.example.flutter_base.dev
fortestcom.example.flutter_base.test

On web, Firebase requires explicit FirebaseOptions. This project reads them from Dart defines in lib/app/firebase_config.dart.

fvm flutter run -d chrome -t lib/main_test.dart `--dart-define=FIREBASE_API_KEY=your-api-key `--dart-define=FIREBASE_APP_ID=your-app-id `--dart-define=FIREBASE_MESSAGING_SENDER_ID=your-sender-id `--dart-define=FIREBASE_PROJECT_ID=your-project-id `--dart-define=FIREBASE_AUTH_DOMAIN=your-project.firebaseapp.com`--dart-define=FIREBASE_STORAGE_BUCKET=your-project.appspot.com`--dart-define=FIREBASE_MEASUREMENT_ID=your-measurement-id

If the required web values are missing, the app skips Firebase on web and disables Firebase Analytics for that run. This prevents:

FirebaseOptions cannot be null when creating the default app.

Project Structure

PathPurpose
lib/main.dartShared app boot sequence used by all flavors
lib/main_dev.dartDevelopment flavor entrypoint
lib/main_test.dartTest flavor entrypoint
lib/main_prod.dartProduction flavor entrypoint
lib/app/app.dartStacked annotations for routes, services, dialogs, and sheets
lib/app/app.locator.dartGenerated service locator
lib/app/app.router.dartGenerated router
lib/app/app.dialogs.dartGenerated dialog setup
lib/app/app.bottomsheets.dartGenerated bottom sheet setup
lib/ui/viewsScreens and ViewModels
lib/ui/commonShared UI helpers and base widgets
lib/servicesApp services registered with Stacked
lib/l10nARB localization source files
lib/generatedGenerated localization output
test/helpersTest service registration and generated mocks
docsProject-specific documentation

Generated files should not be edited by hand. Update the source annotations or ARB files, then regenerate.

Stacked Workflow

Use lib/app/app.dart as the source of truth for Stacked setup.

When adding a new route, service, dialog, or bottom sheet:

  1. Add the class in the correct project folder.
  2. Register it in lib/app/app.dart.
  3. Run code generation.
melos run generate

The same command runs:

fvm dart run intl_utils:generate
fvm dart run build_runner build --delete-conflicting-outputs

If you use the Stacked CLI:

dart pub global activate stacked_cli
stacked create view login
stacked create service authentication
melos run generate

Startup Flow

Boot order:

  1. main_dev.dart, main_test.dart, or main_prod.dart sets FlavorConfig.
  2. mainApp() in lib/main.dart initializes Flutter bindings.
  3. Stacked locator, dialogs, and bottom sheets are set up.
  4. ConnectivityService starts listening for connectivity changes.
  5. Firebase is initialized when config is available.
  6. AnalyticsService creates enabled integrations.
  7. MaterialApp starts at Routes.startupView.
  8. StartupViewModel.runStartupLogic() performs app startup decisions.
  9. Navigation replaces startup with HomeView.

Keep infrastructure setup in mainApp(). Put user-facing startup decisions, such as auth checks, onboarding checks, cached settings, or redirect logic, in StartupViewModel.runStartupLogic().

Services

Services are registered in lib/app/app.dart and accessed through the Stacked locator.

final preferences =locator<SharedPreferencesService>();
await preferences.put('themeMode', 'dark');
final themeMode =await preferences.getString('themeMode');

Available project services:

ServiceFilePurpose
AnalyticsServicelib/services/analytics/analytics_service.dartAnalytics abstraction with Firebase adapter support
ConnectivityServicelib/services/connectivity/connectivity_service.dartTracks online/offline state
SharedPreferencesServicelib/services/shared_preferences/shared_preferences_service.dartTyped wrapper around shared_preferences
FeatureFlaglib/common/feature_flags.dartEnvironment-aware feature flags

DgBaseView in lib/ui/common/base_view.dart uses ConnectivityService to show a no-internet banner by default. Disable it per screen when needed:

DgBaseView(
showConnectivityBanner:false,
child:YourContent(),
);

Localization

Source strings live in lib/l10n/*.arb.

After editing ARB files, regenerate:

melos run strings

The generated localization class is imported as:

import'package:flutter_base/generated/l10n.dart';

Quality Checks

Run these before opening a pull request or sharing the project:

fvm dart format lib test
melos run analyze
melos run test
melos run test:golden

Update golden files only when the UI change is intentional:

melos run update:golden

The analyzer configuration is in analysis_options.yaml and uses total_lints.

Useful Commands

CommandPurpose
melos run initInstall dependencies and Git hooks
melos run generateGenerate localization and Stacked code
melos run stringsGenerate localization only
melos run analyzeRun Flutter analyzer
melos run testRun unit and widget tests
melos run test:goldenRun golden tests
melos run update:goldenUpdate golden snapshots
melos run clear-cacheClean build runner cache
melos run generate-launcher-iconGenerate launcher icons

Common Troubleshooting

dart is not recognized

Add Flutter's bin directory to the Windows PATH. Check with:

where flutter
where dart

If flutter works but dart does not, restart the terminal after updating PATH, or use flutter pub ... commands temporarily.

Firebase Web Options Are Missing

Use the Dart defines shown in the Firebase section. Without them, Firebase is skipped on web by design.

Generated Files Are Out Of Date

Run:

melos run generate

This fixes most missing route, locator, mock, and localization outputs.

Build Runner Has Conflicts

Run:

melos run clear-cache
melos run generate

Included Libraries

AreaLibraries
Architecturestacked, stacked_services, stacked_generator
Firebasefirebase_core, firebase_analytics, firebase_crashlytics
Environmentsflutter_flavor, device_preview
Datahive, hive_flutter, shared_preferences
Connectivityconnectivity_plus
Localizationintl, intl_utils, flutter_localizations
Models and codegenfreezed, freezed_annotation, build_runner
Testingflutter_test, mockito, golden_toolkit, network_image_mock
Workflowfvm, melos, husky, total_lints, flutter_launcher_icons

Before Building A Real App

Update these project defaults:

  1. Rename the app package in pubspec.yaml if flutter_base is not the final package name.
  2. Update Android namespace and applicationId in android/app/build.gradle.kts.
  3. Update iOS bundle IDs in Xcode.
  4. Replace Firebase config files for each flavor.
  5. Replace launcher icons in assets/images and regenerate icons.
  6. Review feature flags in lib/common/feature_flags.dart.

About

Production-ready Flutter boilerplate built on the Stacked framework with essential tools preconfigured—Melos, FVM, Husky, Firebase, localization, linting, state management, database, and more—so you can skip setup and start building scalable, maintainable apps instantly.

Topics

Resources

Stars

2 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Repository files navigation

Stacked Plus

A Flutter starter project built on Stacked. It includes the base architecture, routing, dependency injection, startup logic, Firebase hooks, analytics, localization, shared preferences, connectivity handling, flavors, linting, tests, and development scripts needed to start a production app with less setup work.

For the project-specific startup flow, read docs/stacked-startup-logic.md.

Quick Start

Use this path when setting up the project for the first time.

# 1. Check Flutter is available
flutter --version
flutter doctor
# 2. Install FVM if it is not already installed
dart pub global activate fvm
# 3. Install the Flutter SDK version from .fvmrc
fvm install
# 4. Install Melos if it is not already installed
dart pub global activate melos
# 5. Install dependencies and Git hooks
melos run init
# 6. Generate localization, routes, locator, mocks, and other generated code
melos run generate
# 7. Run analyzer and tests
melos run analyze
melos run test

If dart is not recognized on Windows, add the Flutter SDK bin directory to your PATH, then restart the terminal. The Flutter SDK provides both flutter and dart.

As a temporary fallback, use Flutter commands directly:

flutter pub get
flutter pub global activate fvm
flutter pub global activate melos

Running The App

This project has three flavor entrypoints:

EnvironmentDart entrypointNative flavorMelos command
Testlib/main_test.dartfortestmelos run run:test
Developmentlib/main_dev.dartdevelopmentmelos run run:dev
Productionlib/main_prod.dartproductionmelos run run:prod

Equivalent raw Flutter commands:

fvm flutter run -t lib/main_test.dart --flavor fortest
fvm flutter run -t lib/main_dev.dart --flavor development
fvm flutter run -t lib/main_prod.dart --flavor production

For web:

melos run web-run:test
melos run web-run:dev
melos run web-run:prod

Firebase Setup

Firebase is initialized in lib/app/setup_firebase.dart.

On mobile, Firebase.initializeApp() uses native Firebase config files:

PlatformConfig file
Android testandroid/app/src/fortest/google-services.json
Android developmentandroid/app/src/development/google-services.json
Android productionandroid/app/src/production/google-services.json
iOSAdd the matching GoogleService-Info.plist to the Runner target/scheme

The Android application IDs are configured in android/app/build.gradle.kts:

FlavorApplication ID
productioncom.example.flutter_base
developmentcom.example.flutter_base.dev
fortestcom.example.flutter_base.test

On web, Firebase requires explicit FirebaseOptions. This project reads them from Dart defines in lib/app/firebase_config.dart.

fvm flutter run -d chrome -t lib/main_test.dart `--dart-define=FIREBASE_API_KEY=your-api-key `--dart-define=FIREBASE_APP_ID=your-app-id `--dart-define=FIREBASE_MESSAGING_SENDER_ID=your-sender-id `--dart-define=FIREBASE_PROJECT_ID=your-project-id `--dart-define=FIREBASE_AUTH_DOMAIN=your-project.firebaseapp.com`--dart-define=FIREBASE_STORAGE_BUCKET=your-project.appspot.com`--dart-define=FIREBASE_MEASUREMENT_ID=your-measurement-id

If the required web values are missing, the app skips Firebase on web and disables Firebase Analytics for that run. This prevents:

FirebaseOptions cannot be null when creating the default app.

Project Structure

PathPurpose
lib/main.dartShared app boot sequence used by all flavors
lib/main_dev.dartDevelopment flavor entrypoint
lib/main_test.dartTest flavor entrypoint
lib/main_prod.dartProduction flavor entrypoint
lib/app/app.dartStacked annotations for routes, services, dialogs, and sheets
lib/app/app.locator.dartGenerated service locator
lib/app/app.router.dartGenerated router
lib/app/app.dialogs.dartGenerated dialog setup
lib/app/app.bottomsheets.dartGenerated bottom sheet setup
lib/ui/viewsScreens and ViewModels
lib/ui/commonShared UI helpers and base widgets
lib/servicesApp services registered with Stacked
lib/l10nARB localization source files
lib/generatedGenerated localization output
test/helpersTest service registration and generated mocks
docsProject-specific documentation

Generated files should not be edited by hand. Update the source annotations or ARB files, then regenerate.

Stacked Workflow

Use lib/app/app.dart as the source of truth for Stacked setup.

When adding a new route, service, dialog, or bottom sheet:

  1. Add the class in the correct project folder.
  2. Register it in lib/app/app.dart.
  3. Run code generation.
melos run generate

The same command runs:

fvm dart run intl_utils:generate
fvm dart run build_runner build --delete-conflicting-outputs

If you use the Stacked CLI:

dart pub global activate stacked_cli
stacked create view login
stacked create service authentication
melos run generate

Startup Flow

Boot order:

  1. main_dev.dart, main_test.dart, or main_prod.dart sets FlavorConfig.
  2. mainApp() in lib/main.dart initializes Flutter bindings.
  3. Stacked locator, dialogs, and bottom sheets are set up.
  4. ConnectivityService starts listening for connectivity changes.
  5. Firebase is initialized when config is available.
  6. AnalyticsService creates enabled integrations.
  7. MaterialApp starts at Routes.startupView.
  8. StartupViewModel.runStartupLogic() performs app startup decisions.
  9. Navigation replaces startup with HomeView.

Keep infrastructure setup in mainApp(). Put user-facing startup decisions, such as auth checks, onboarding checks, cached settings, or redirect logic, in StartupViewModel.runStartupLogic().

Services

Services are registered in lib/app/app.dart and accessed through the Stacked locator.

final preferences =locator<SharedPreferencesService>();
await preferences.put('themeMode', 'dark');
final themeMode =await preferences.getString('themeMode');

Available project services:

ServiceFilePurpose
AnalyticsServicelib/services/analytics/analytics_service.dartAnalytics abstraction with Firebase adapter support
ConnectivityServicelib/services/connectivity/connectivity_service.dartTracks online/offline state
SharedPreferencesServicelib/services/shared_preferences/shared_preferences_service.dartTyped wrapper around shared_preferences
FeatureFlaglib/common/feature_flags.dartEnvironment-aware feature flags

DgBaseView in lib/ui/common/base_view.dart uses ConnectivityService to show a no-internet banner by default. Disable it per screen when needed:

DgBaseView(
showConnectivityBanner:false,
child:YourContent(),
);

Localization

Source strings live in lib/l10n/*.arb.

After editing ARB files, regenerate:

melos run strings

The generated localization class is imported as:

import'package:flutter_base/generated/l10n.dart';

Quality Checks

Run these before opening a pull request or sharing the project:

fvm dart format lib test
melos run analyze
melos run test
melos run test:golden

Update golden files only when the UI change is intentional:

melos run update:golden

The analyzer configuration is in analysis_options.yaml and uses total_lints.

Useful Commands

CommandPurpose
melos run initInstall dependencies and Git hooks
melos run generateGenerate localization and Stacked code
melos run stringsGenerate localization only
melos run analyzeRun Flutter analyzer
melos run testRun unit and widget tests
melos run test:goldenRun golden tests
melos run update:goldenUpdate golden snapshots
melos run clear-cacheClean build runner cache
melos run generate-launcher-iconGenerate launcher icons

Common Troubleshooting

dart is not recognized

Add Flutter's bin directory to the Windows PATH. Check with:

where flutter
where dart

If flutter works but dart does not, restart the terminal after updating PATH, or use flutter pub ... commands temporarily.

Firebase Web Options Are Missing

Use the Dart defines shown in the Firebase section. Without them, Firebase is skipped on web by design.

Generated Files Are Out Of Date

Run:

melos run generate

This fixes most missing route, locator, mock, and localization outputs.

Build Runner Has Conflicts

Run:

melos run clear-cache
melos run generate

Included Libraries

AreaLibraries
Architecturestacked, stacked_services, stacked_generator
Firebasefirebase_core, firebase_analytics, firebase_crashlytics
Environmentsflutter_flavor, device_preview
Datahive, hive_flutter, shared_preferences
Connectivityconnectivity_plus
Localizationintl, intl_utils, flutter_localizations
Models and codegenfreezed, freezed_annotation, build_runner
Testingflutter_test, mockito, golden_toolkit, network_image_mock
Workflowfvm, melos, husky, total_lints, flutter_launcher_icons

Before Building A Real App

Update these project defaults:

  1. Rename the app package in pubspec.yaml if flutter_base is not the final package name.
  2. Update Android namespace and applicationId in android/app/build.gradle.kts.
  3. Update iOS bundle IDs in Xcode.
  4. Replace Firebase config files for each flavor.
  5. Replace launcher icons in assets/images and regenerate icons.
  6. Review feature flags in lib/common/feature_flags.dart.

About

Production-ready Flutter boilerplate built on the Stacked framework with essential tools preconfigured—Melos, FVM, Husky, Firebase, localization, linting, state management, database, and more—so you can skip setup and start building scalable, maintainable apps instantly.

Topics

Resources

Stars

2 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

Stacked Plus

A Flutter starter project built on Stacked. It includes the base architecture, routing, dependency injection, startup logic, Firebase hooks, analytics, localization, shared preferences, connectivity handling, flavors, linting, tests, and development scripts needed to start a production app with less setup work.

For the project-specific startup flow, read docs/stacked-startup-logic.md.

Quick Start

Use this path when setting up the project for the first time.

# 1. Check Flutter is available
flutter --version
flutter doctor
# 2. Install FVM if it is not already installed
dart pub global activate fvm
# 3. Install the Flutter SDK version from .fvmrc
fvm install
# 4. Install Melos if it is not already installed
dart pub global activate melos
# 5. Install dependencies and Git hooks
melos run init
# 6. Generate localization, routes, locator, mocks, and other generated code
melos run generate
# 7. Run analyzer and tests
melos run analyze
melos run test

If dart is not recognized on Windows, add the Flutter SDK bin directory to your PATH, then restart the terminal. The Flutter SDK provides both flutter and dart.

As a temporary fallback, use Flutter commands directly:

flutter pub get
flutter pub global activate fvm
flutter pub global activate melos

Running The App

This project has three flavor entrypoints:

EnvironmentDart entrypointNative flavorMelos command
Testlib/main_test.dartfortestmelos run run:test
Developmentlib/main_dev.dartdevelopmentmelos run run:dev
Productionlib/main_prod.dartproductionmelos run run:prod

Equivalent raw Flutter commands:

fvm flutter run -t lib/main_test.dart --flavor fortest
fvm flutter run -t lib/main_dev.dart --flavor development
fvm flutter run -t lib/main_prod.dart --flavor production

For web:

melos run web-run:test
melos run web-run:dev
melos run web-run:prod

Firebase Setup

Firebase is initialized in lib/app/setup_firebase.dart.

On mobile, Firebase.initializeApp() uses native Firebase config files:

PlatformConfig file
Android testandroid/app/src/fortest/google-services.json
Android developmentandroid/app/src/development/google-services.json
Android productionandroid/app/src/production/google-services.json
iOSAdd the matching GoogleService-Info.plist to the Runner target/scheme

The Android application IDs are configured in android/app/build.gradle.kts:

FlavorApplication ID
productioncom.example.flutter_base
developmentcom.example.flutter_base.dev
fortestcom.example.flutter_base.test

On web, Firebase requires explicit FirebaseOptions. This project reads them from Dart defines in lib/app/firebase_config.dart.

fvm flutter run -d chrome -t lib/main_test.dart `--dart-define=FIREBASE_API_KEY=your-api-key `--dart-define=FIREBASE_APP_ID=your-app-id `--dart-define=FIREBASE_MESSAGING_SENDER_ID=your-sender-id `--dart-define=FIREBASE_PROJECT_ID=your-project-id `--dart-define=FIREBASE_AUTH_DOMAIN=your-project.firebaseapp.com`--dart-define=FIREBASE_STORAGE_BUCKET=your-project.appspot.com`--dart-define=FIREBASE_MEASUREMENT_ID=your-measurement-id

If the required web values are missing, the app skips Firebase on web and disables Firebase Analytics for that run. This prevents:

FirebaseOptions cannot be null when creating the default app.

Project Structure

PathPurpose
lib/main.dartShared app boot sequence used by all flavors
lib/main_dev.dartDevelopment flavor entrypoint
lib/main_test.dartTest flavor entrypoint
lib/main_prod.dartProduction flavor entrypoint
lib/app/app.dartStacked annotations for routes, services, dialogs, and sheets
lib/app/app.locator.dartGenerated service locator
lib/app/app.router.dartGenerated router
lib/app/app.dialogs.dartGenerated dialog setup
lib/app/app.bottomsheets.dartGenerated bottom sheet setup
lib/ui/viewsScreens and ViewModels
lib/ui/commonShared UI helpers and base widgets
lib/servicesApp services registered with Stacked
lib/l10nARB localization source files
lib/generatedGenerated localization output
test/helpersTest service registration and generated mocks
docsProject-specific documentation

Generated files should not be edited by hand. Update the source annotations or ARB files, then regenerate.

Stacked Workflow

Use lib/app/app.dart as the source of truth for Stacked setup.

When adding a new route, service, dialog, or bottom sheet:

  1. Add the class in the correct project folder.
  2. Register it in lib/app/app.dart.
  3. Run code generation.
melos run generate

The same command runs:

fvm dart run intl_utils:generate
fvm dart run build_runner build --delete-conflicting-outputs

If you use the Stacked CLI:

dart pub global activate stacked_cli
stacked create view login
stacked create service authentication
melos run generate

Startup Flow

Boot order:

  1. main_dev.dart, main_test.dart, or main_prod.dart sets FlavorConfig.
  2. mainApp() in lib/main.dart initializes Flutter bindings.
  3. Stacked locator, dialogs, and bottom sheets are set up.
  4. ConnectivityService starts listening for connectivity changes.
  5. Firebase is initialized when config is available.
  6. AnalyticsService creates enabled integrations.
  7. MaterialApp starts at Routes.startupView.
  8. StartupViewModel.runStartupLogic() performs app startup decisions.
  9. Navigation replaces startup with HomeView.

Keep infrastructure setup in mainApp(). Put user-facing startup decisions, such as auth checks, onboarding checks, cached settings, or redirect logic, in StartupViewModel.runStartupLogic().

Services

Services are registered in lib/app/app.dart and accessed through the Stacked locator.

final preferences =locator<SharedPreferencesService>();
await preferences.put('themeMode', 'dark');
final themeMode =await preferences.getString('themeMode');

Available project services:

ServiceFilePurpose
AnalyticsServicelib/services/analytics/analytics_service.dartAnalytics abstraction with Firebase adapter support
ConnectivityServicelib/services/connectivity/connectivity_service.dartTracks online/offline state
SharedPreferencesServicelib/services/shared_preferences/shared_preferences_service.dartTyped wrapper around shared_preferences
FeatureFlaglib/common/feature_flags.dartEnvironment-aware feature flags

DgBaseView in lib/ui/common/base_view.dart uses ConnectivityService to show a no-internet banner by default. Disable it per screen when needed:

DgBaseView(
showConnectivityBanner:false,
child:YourContent(),
);

Localization

Source strings live in lib/l10n/*.arb.

After editing ARB files, regenerate:

melos run strings

The generated localization class is imported as:

import'package:flutter_base/generated/l10n.dart';

Quality Checks

Run these before opening a pull request or sharing the project:

fvm dart format lib test
melos run analyze
melos run test
melos run test:golden

Update golden files only when the UI change is intentional:

melos run update:golden

The analyzer configuration is in analysis_options.yaml and uses total_lints.

Useful Commands

CommandPurpose
melos run initInstall dependencies and Git hooks
melos run generateGenerate localization and Stacked code
melos run stringsGenerate localization only
melos run analyzeRun Flutter analyzer
melos run testRun unit and widget tests
melos run test:goldenRun golden tests
melos run update:goldenUpdate golden snapshots
melos run clear-cacheClean build runner cache
melos run generate-launcher-iconGenerate launcher icons

Common Troubleshooting

dart is not recognized

Add Flutter's bin directory to the Windows PATH. Check with:

where flutter
where dart

If flutter works but dart does not, restart the terminal after updating PATH, or use flutter pub ... commands temporarily.

Firebase Web Options Are Missing

Use the Dart defines shown in the Firebase section. Without them, Firebase is skipped on web by design.

Generated Files Are Out Of Date

Run:

melos run generate

This fixes most missing route, locator, mock, and localization outputs.

Build Runner Has Conflicts

Run:

melos run clear-cache
melos run generate

Included Libraries

AreaLibraries
Architecturestacked, stacked_services, stacked_generator
Firebasefirebase_core, firebase_analytics, firebase_crashlytics
Environmentsflutter_flavor, device_preview
Datahive, hive_flutter, shared_preferences
Connectivityconnectivity_plus
Localizationintl, intl_utils, flutter_localizations
Models and codegenfreezed, freezed_annotation, build_runner
Testingflutter_test, mockito, golden_toolkit, network_image_mock
Workflowfvm, melos, husky, total_lints, flutter_launcher_icons

Before Building A Real App

Update these project defaults:

  1. Rename the app package in pubspec.yaml if flutter_base is not the final package name.
  2. Update Android namespace and applicationId in android/app/build.gradle.kts.
  3. Update iOS bundle IDs in Xcode.
  4. Replace Firebase config files for each flavor.
  5. Replace launcher icons in assets/images and regenerate icons.
  6. Review feature flags in lib/common/feature_flags.dart.

About

Production-ready Flutter boilerplate built on the Stacked framework with essential tools preconfigured—Melos, FVM, Husky, Firebase, localization, linting, state management, database, and more—so you can skip setup and start building scalable, maintainable apps instantly.

Topics

Resources

Stars

2 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

Stacked Plus

A Flutter starter project built on Stacked. It includes the base architecture, routing, dependency injection, startup logic, Firebase hooks, analytics, localization, shared preferences, connectivity handling, flavors, linting, tests, and development scripts needed to start a production app with less setup work.

For the project-specific startup flow, read docs/stacked-startup-logic.md.

Quick Start

Use this path when setting up the project for the first time.

# 1. Check Flutter is available
flutter --version
flutter doctor
# 2. Install FVM if it is not already installed
dart pub global activate fvm
# 3. Install the Flutter SDK version from .fvmrc
fvm install
# 4. Install Melos if it is not already installed
dart pub global activate melos
# 5. Install dependencies and Git hooks
melos run init
# 6. Generate localization, routes, locator, mocks, and other generated code
melos run generate
# 7. Run analyzer and tests
melos run analyze
melos run test

If dart is not recognized on Windows, add the Flutter SDK bin directory to your PATH, then restart the terminal. The Flutter SDK provides both flutter and dart.

As a temporary fallback, use Flutter commands directly:

flutter pub get
flutter pub global activate fvm
flutter pub global activate melos

Running The App

This project has three flavor entrypoints:

EnvironmentDart entrypointNative flavorMelos command
Testlib/main_test.dartfortestmelos run run:test
Developmentlib/main_dev.dartdevelopmentmelos run run:dev
Productionlib/main_prod.dartproductionmelos run run:prod

Equivalent raw Flutter commands:

fvm flutter run -t lib/main_test.dart --flavor fortest
fvm flutter run -t lib/main_dev.dart --flavor development
fvm flutter run -t lib/main_prod.dart --flavor production

For web:

melos run web-run:test
melos run web-run:dev
melos run web-run:prod

Firebase Setup

Firebase is initialized in lib/app/setup_firebase.dart.

On mobile, Firebase.initializeApp() uses native Firebase config files:

PlatformConfig file
Android testandroid/app/src/fortest/google-services.json
Android developmentandroid/app/src/development/google-services.json
Android productionandroid/app/src/production/google-services.json
iOSAdd the matching GoogleService-Info.plist to the Runner target/scheme

The Android application IDs are configured in android/app/build.gradle.kts:

FlavorApplication ID
productioncom.example.flutter_base
developmentcom.example.flutter_base.dev
fortestcom.example.flutter_base.test

On web, Firebase requires explicit FirebaseOptions. This project reads them from Dart defines in lib/app/firebase_config.dart.

fvm flutter run -d chrome -t lib/main_test.dart `--dart-define=FIREBASE_API_KEY=your-api-key `--dart-define=FIREBASE_APP_ID=your-app-id `--dart-define=FIREBASE_MESSAGING_SENDER_ID=your-sender-id `--dart-define=FIREBASE_PROJECT_ID=your-project-id `--dart-define=FIREBASE_AUTH_DOMAIN=your-project.firebaseapp.com`--dart-define=FIREBASE_STORAGE_BUCKET=your-project.appspot.com`--dart-define=FIREBASE_MEASUREMENT_ID=your-measurement-id

If the required web values are missing, the app skips Firebase on web and disables Firebase Analytics for that run. This prevents:

FirebaseOptions cannot be null when creating the default app.

Project Structure

PathPurpose
lib/main.dartShared app boot sequence used by all flavors
lib/main_dev.dartDevelopment flavor entrypoint
lib/main_test.dartTest flavor entrypoint
lib/main_prod.dartProduction flavor entrypoint
lib/app/app.dartStacked annotations for routes, services, dialogs, and sheets
lib/app/app.locator.dartGenerated service locator
lib/app/app.router.dartGenerated router
lib/app/app.dialogs.dartGenerated dialog setup
lib/app/app.bottomsheets.dartGenerated bottom sheet setup
lib/ui/viewsScreens and ViewModels
lib/ui/commonShared UI helpers and base widgets
lib/servicesApp services registered with Stacked
lib/l10nARB localization source files
lib/generatedGenerated localization output
test/helpersTest service registration and generated mocks
docsProject-specific documentation

Generated files should not be edited by hand. Update the source annotations or ARB files, then regenerate.

Stacked Workflow

Use lib/app/app.dart as the source of truth for Stacked setup.

When adding a new route, service, dialog, or bottom sheet:

  1. Add the class in the correct project folder.
  2. Register it in lib/app/app.dart.
  3. Run code generation.
melos run generate

The same command runs:

fvm dart run intl_utils:generate
fvm dart run build_runner build --delete-conflicting-outputs

If you use the Stacked CLI:

dart pub global activate stacked_cli
stacked create view login
stacked create service authentication
melos run generate

Startup Flow

Boot order:

  1. main_dev.dart, main_test.dart, or main_prod.dart sets FlavorConfig.
  2. mainApp() in lib/main.dart initializes Flutter bindings.
  3. Stacked locator, dialogs, and bottom sheets are set up.
  4. ConnectivityService starts listening for connectivity changes.
  5. Firebase is initialized when config is available.
  6. AnalyticsService creates enabled integrations.
  7. MaterialApp starts at Routes.startupView.
  8. StartupViewModel.runStartupLogic() performs app startup decisions.
  9. Navigation replaces startup with HomeView.

Keep infrastructure setup in mainApp(). Put user-facing startup decisions, such as auth checks, onboarding checks, cached settings, or redirect logic, in StartupViewModel.runStartupLogic().

Services

Services are registered in lib/app/app.dart and accessed through the Stacked locator.

final preferences =locator<SharedPreferencesService>();
await preferences.put('themeMode', 'dark');
final themeMode =await preferences.getString('themeMode');

Available project services:

ServiceFilePurpose
AnalyticsServicelib/services/analytics/analytics_service.dartAnalytics abstraction with Firebase adapter support
ConnectivityServicelib/services/connectivity/connectivity_service.dartTracks online/offline state
SharedPreferencesServicelib/services/shared_preferences/shared_preferences_service.dartTyped wrapper around shared_preferences
FeatureFlaglib/common/feature_flags.dartEnvironment-aware feature flags

DgBaseView in lib/ui/common/base_view.dart uses ConnectivityService to show a no-internet banner by default. Disable it per screen when needed:

DgBaseView(
showConnectivityBanner:false,
child:YourContent(),
);

Localization

Source strings live in lib/l10n/*.arb.

After editing ARB files, regenerate:

melos run strings

The generated localization class is imported as:

import'package:flutter_base/generated/l10n.dart';

Quality Checks

Run these before opening a pull request or sharing the project:

fvm dart format lib test
melos run analyze
melos run test
melos run test:golden

Update golden files only when the UI change is intentional:

melos run update:golden

The analyzer configuration is in analysis_options.yaml and uses total_lints.

Useful Commands

CommandPurpose
melos run initInstall dependencies and Git hooks
melos run generateGenerate localization and Stacked code
melos run stringsGenerate localization only
melos run analyzeRun Flutter analyzer
melos run testRun unit and widget tests
melos run test:goldenRun golden tests
melos run update:goldenUpdate golden snapshots
melos run clear-cacheClean build runner cache
melos run generate-launcher-iconGenerate launcher icons

Common Troubleshooting

dart is not recognized

Add Flutter's bin directory to the Windows PATH. Check with:

where flutter
where dart

If flutter works but dart does not, restart the terminal after updating PATH, or use flutter pub ... commands temporarily.

Firebase Web Options Are Missing

Use the Dart defines shown in the Firebase section. Without them, Firebase is skipped on web by design.

Generated Files Are Out Of Date

Run:

melos run generate

This fixes most missing route, locator, mock, and localization outputs.

Build Runner Has Conflicts

Run:

melos run clear-cache
melos run generate

Included Libraries

AreaLibraries
Architecturestacked, stacked_services, stacked_generator
Firebasefirebase_core, firebase_analytics, firebase_crashlytics
Environmentsflutter_flavor, device_preview
Datahive, hive_flutter, shared_preferences
Connectivityconnectivity_plus
Localizationintl, intl_utils, flutter_localizations
Models and codegenfreezed, freezed_annotation, build_runner
Testingflutter_test, mockito, golden_toolkit, network_image_mock
Workflowfvm, melos, husky, total_lints, flutter_launcher_icons

Before Building A Real App

Update these project defaults:

  1. Rename the app package in pubspec.yaml if flutter_base is not the final package name.
  2. Update Android namespace and applicationId in android/app/build.gradle.kts.
  3. Update iOS bundle IDs in Xcode.
  4. Replace Firebase config files for each flavor.
  5. Replace launcher icons in assets/images and regenerate icons.
  6. Review feature flags in lib/common/feature_flags.dart.

About

Production-ready Flutter boilerplate built on the Stacked framework with essential tools preconfigured—Melos, FVM, Husky, Firebase, localization, linting, state management, database, and more—so you can skip setup and start building scalable, maintainable apps instantly.

Topics

Resources

Stars

2 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Repository files navigation

Stacked Plus

A Flutter starter project built on Stacked. It includes the base architecture, routing, dependency injection, startup logic, Firebase hooks, analytics, localization, shared preferences, connectivity handling, flavors, linting, tests, and development scripts needed to start a production app with less setup work.

For the project-specific startup flow, read docs/stacked-startup-logic.md.

Quick Start

Use this path when setting up the project for the first time.

# 1. Check Flutter is available
flutter --version
flutter doctor
# 2. Install FVM if it is not already installed
dart pub global activate fvm
# 3. Install the Flutter SDK version from .fvmrc
fvm install
# 4. Install Melos if it is not already installed
dart pub global activate melos
# 5. Install dependencies and Git hooks
melos run init
# 6. Generate localization, routes, locator, mocks, and other generated code
melos run generate
# 7. Run analyzer and tests
melos run analyze
melos run test

If dart is not recognized on Windows, add the Flutter SDK bin directory to your PATH, then restart the terminal. The Flutter SDK provides both flutter and dart.

As a temporary fallback, use Flutter commands directly:

flutter pub get
flutter pub global activate fvm
flutter pub global activate melos

Running The App

This project has three flavor entrypoints:

EnvironmentDart entrypointNative flavorMelos command
Testlib/main_test.dartfortestmelos run run:test
Developmentlib/main_dev.dartdevelopmentmelos run run:dev
Productionlib/main_prod.dartproductionmelos run run:prod

Equivalent raw Flutter commands:

fvm flutter run -t lib/main_test.dart --flavor fortest
fvm flutter run -t lib/main_dev.dart --flavor development
fvm flutter run -t lib/main_prod.dart --flavor production

For web:

melos run web-run:test
melos run web-run:dev
melos run web-run:prod

Firebase Setup

Firebase is initialized in lib/app/setup_firebase.dart.

On mobile, Firebase.initializeApp() uses native Firebase config files:

PlatformConfig file
Android testandroid/app/src/fortest/google-services.json
Android developmentandroid/app/src/development/google-services.json
Android productionandroid/app/src/production/google-services.json
iOSAdd the matching GoogleService-Info.plist to the Runner target/scheme

The Android application IDs are configured in android/app/build.gradle.kts:

FlavorApplication ID
productioncom.example.flutter_base
developmentcom.example.flutter_base.dev
fortestcom.example.flutter_base.test

On web, Firebase requires explicit FirebaseOptions. This project reads them from Dart defines in lib/app/firebase_config.dart.

fvm flutter run -d chrome -t lib/main_test.dart `--dart-define=FIREBASE_API_KEY=your-api-key `--dart-define=FIREBASE_APP_ID=your-app-id `--dart-define=FIREBASE_MESSAGING_SENDER_ID=your-sender-id `--dart-define=FIREBASE_PROJECT_ID=your-project-id `--dart-define=FIREBASE_AUTH_DOMAIN=your-project.firebaseapp.com`--dart-define=FIREBASE_STORAGE_BUCKET=your-project.appspot.com`--dart-define=FIREBASE_MEASUREMENT_ID=your-measurement-id

If the required web values are missing, the app skips Firebase on web and disables Firebase Analytics for that run. This prevents:

FirebaseOptions cannot be null when creating the default app.

Project Structure

PathPurpose
lib/main.dartShared app boot sequence used by all flavors
lib/main_dev.dartDevelopment flavor entrypoint
lib/main_test.dartTest flavor entrypoint
lib/main_prod.dartProduction flavor entrypoint
lib/app/app.dartStacked annotations for routes, services, dialogs, and sheets
lib/app/app.locator.dartGenerated service locator
lib/app/app.router.dartGenerated router
lib/app/app.dialogs.dartGenerated dialog setup
lib/app/app.bottomsheets.dartGenerated bottom sheet setup
lib/ui/viewsScreens and ViewModels
lib/ui/commonShared UI helpers and base widgets
lib/servicesApp services registered with Stacked
lib/l10nARB localization source files
lib/generatedGenerated localization output
test/helpersTest service registration and generated mocks
docsProject-specific documentation

Generated files should not be edited by hand. Update the source annotations or ARB files, then regenerate.

Stacked Workflow

Use lib/app/app.dart as the source of truth for Stacked setup.

When adding a new route, service, dialog, or bottom sheet:

  1. Add the class in the correct project folder.
  2. Register it in lib/app/app.dart.
  3. Run code generation.
melos run generate

The same command runs:

fvm dart run intl_utils:generate
fvm dart run build_runner build --delete-conflicting-outputs

If you use the Stacked CLI:

dart pub global activate stacked_cli
stacked create view login
stacked create service authentication
melos run generate

Startup Flow

Boot order:

  1. main_dev.dart, main_test.dart, or main_prod.dart sets FlavorConfig.
  2. mainApp() in lib/main.dart initializes Flutter bindings.
  3. Stacked locator, dialogs, and bottom sheets are set up.
  4. ConnectivityService starts listening for connectivity changes.
  5. Firebase is initialized when config is available.
  6. AnalyticsService creates enabled integrations.
  7. MaterialApp starts at Routes.startupView.
  8. StartupViewModel.runStartupLogic() performs app startup decisions.
  9. Navigation replaces startup with HomeView.

Keep infrastructure setup in mainApp(). Put user-facing startup decisions, such as auth checks, onboarding checks, cached settings, or redirect logic, in StartupViewModel.runStartupLogic().

Services

Services are registered in lib/app/app.dart and accessed through the Stacked locator.

final preferences =locator<SharedPreferencesService>();
await preferences.put('themeMode', 'dark');
final themeMode =await preferences.getString('themeMode');

Available project services:

ServiceFilePurpose
AnalyticsServicelib/services/analytics/analytics_service.dartAnalytics abstraction with Firebase adapter support
ConnectivityServicelib/services/connectivity/connectivity_service.dartTracks online/offline state
SharedPreferencesServicelib/services/shared_preferences/shared_preferences_service.dartTyped wrapper around shared_preferences
FeatureFlaglib/common/feature_flags.dartEnvironment-aware feature flags

DgBaseView in lib/ui/common/base_view.dart uses ConnectivityService to show a no-internet banner by default. Disable it per screen when needed:

DgBaseView(
showConnectivityBanner:false,
child:YourContent(),
);

Localization

Source strings live in lib/l10n/*.arb.

After editing ARB files, regenerate:

melos run strings

The generated localization class is imported as:

import'package:flutter_base/generated/l10n.dart';

Quality Checks

Run these before opening a pull request or sharing the project:

fvm dart format lib test
melos run analyze
melos run test
melos run test:golden

Update golden files only when the UI change is intentional:

melos run update:golden

The analyzer configuration is in analysis_options.yaml and uses total_lints.

Useful Commands

CommandPurpose
melos run initInstall dependencies and Git hooks
melos run generateGenerate localization and Stacked code
melos run stringsGenerate localization only
melos run analyzeRun Flutter analyzer
melos run testRun unit and widget tests
melos run test:goldenRun golden tests
melos run update:goldenUpdate golden snapshots
melos run clear-cacheClean build runner cache
melos run generate-launcher-iconGenerate launcher icons

Common Troubleshooting

dart is not recognized

Add Flutter's bin directory to the Windows PATH. Check with:

where flutter
where dart

If flutter works but dart does not, restart the terminal after updating PATH, or use flutter pub ... commands temporarily.

Firebase Web Options Are Missing

Use the Dart defines shown in the Firebase section. Without them, Firebase is skipped on web by design.

Generated Files Are Out Of Date

Run:

melos run generate

This fixes most missing route, locator, mock, and localization outputs.

Build Runner Has Conflicts

Run:

melos run clear-cache
melos run generate

Included Libraries

AreaLibraries
Architecturestacked, stacked_services, stacked_generator
Firebasefirebase_core, firebase_analytics, firebase_crashlytics
Environmentsflutter_flavor, device_preview
Datahive, hive_flutter, shared_preferences
Connectivityconnectivity_plus
Localizationintl, intl_utils, flutter_localizations
Models and codegenfreezed, freezed_annotation, build_runner
Testingflutter_test, mockito, golden_toolkit, network_image_mock
Workflowfvm, melos, husky, total_lints, flutter_launcher_icons

Before Building A Real App

Update these project defaults:

  1. Rename the app package in pubspec.yaml if flutter_base is not the final package name.
  2. Update Android namespace and applicationId in android/app/build.gradle.kts.
  3. Update iOS bundle IDs in Xcode.
  4. Replace Firebase config files for each flavor.
  5. Replace launcher icons in assets/images and regenerate icons.
  6. Review feature flags in lib/common/feature_flags.dart.

About

Production-ready Flutter boilerplate built on the Stacked framework with essential tools preconfigured—Melos, FVM, Husky, Firebase, localization, linting, state management, database, and more—so you can skip setup and start building scalable, maintainable apps instantly.

Topics

Resources

Stars

2 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages