Core Scaffolding
How to add an app initializer to a Flutter app
Free Reference for initializer_skeleton: every variable, option and package it generates. Command: archipelago generate initializer_skeleton
Generate a pre-launch or post-launch initializer, learn the two-phase startup pattern, and wire your own SDK into the bootstrap sequence.
What you'll learn
- Generating pre-launch and post-launch initializers
- Understanding the two-phase initialization pattern
- Wiring initializers into your app's bootstrap sequence
- Creating custom initializers for your own SDKs
Prerequisites
- An existing Archipelago monorepo (see Monorepo Scaffolding)
- Familiarity with the Two-Phase Init pattern
Step 1: Generate an Initializer
archipelago generate initializer_skeletonYou will be prompted for:
- appName: your app name, for example
MyApp - initializerType:
pre_launchorpost_launch - initializerName: for example
Analytics,PaymentorFeatureFlags
Or use a config file:
{
"appName": "MyApp",
"initializerType": "pre_launch",
"initializerName": "Analytics"
}archipelago generate initializer_skeleton --config init_config.jsonStep 2: Understand the Generated Structure
The brick generates one file in the host app. It does not create the app. Run it in an app made by app_scaffold or flutter_modular_monorepo.
apps/my_app/lib/host/initializers/
└── analytics_app_initializer.dartThe class extends the Initializer base class and returns an InitializerResult:
class AnalyticsAppInitializer extends Initializer {
const AnalyticsAppInitializer();
// Pre-launch only
@override
bool get canRunInParallel => false;
@override
Future<InitializerResult> initialize() async {
try {
// TODO: Add analytics initialization logic
return const InitializerResult.success();
} catch (e) {
return InitializerResult.failure(e);
}
}
@override
Future<bool> dispose() async => true;
}Pre-launch initializers run one after another. Post-launch initializers keep the default canRunInParallel of true.
Step 3: Pre-Launch vs Post-Launch
The initializerType determines when the initializer runs:
| Type | When it Runs | Use For |
|---|---|---|
pre_launch | Before the first frame renders (blocking) | DI setup, route registration, critical SDKs |
post_launch | After the first frame renders (non-blocking) | Analytics, feature flags, remote config |
Pre-launch initializers block the splash screen. Keep them fast. Post-launch initializers run after your app is visible. The runner applies per-initializer timeouts and reports failures to monitoring.
Step 4: Check the Registration
The brick registers the initializer for you. Open pre_launch_initializer.dart or post_launch_initializer.dart and look between the markers:
// archipelago:post_launch_initializers:start
AnalyticsAppInitializer(),
// archipelago:post_launch_initializers:endRunning the brick again does not add a second entry. To remove an initializer, delete its file, its import and its list line. If your app has no markers, post_gen prints a warning and you add the import and entry by hand.
Step 5: Add Your Logic
Fill in initialize(). Take what you need as constructor parameters and pass them from the list. Resolve registered types in the host list, not inside the class:
class AnalyticsAppInitializer extends Initializer {
const AnalyticsAppInitializer(this._tracker);
final AnalyticTracker _tracker;
@override
Future<InitializerResult> initialize() async {
try {
await _tracker.setUserProperty('plan', 'free');
return const InitializerResult.success();
} catch (e) {
return InitializerResult.failure(e);
}
}
@override
Future<bool> dispose() async => true;
}Then change the generated list entry to AnalyticsAppInitializer(getIt<AnalyticTracker>()). A pre-launch failure stops the app and shows the error screen. A post-launch failure is reported and the app keeps running.
Common Customizations
| Customization | How |
|---|---|
| Add dependencies | Constructor parameters, filled in the host list |
| Add error handling | Return InitializerResult.failure(e) from the catch block |
| Add timeout | Future.timeout() inside initialize() |
| Order initializers | Reorder the lines between the markers. Entries append in generation order |
Next Steps
- Understand Two-Phase Init for the full pattern
- Set up Monitoring to track initialization failures