ArchitectureMedium30 XP3 min read
How do you architect app initialization in Flutter?
TL;DR: Use a dedicated AppInitializer class (or a use case) called from main() before runApp(). Initialize services in dependency order: Firebase → Hive → GetIt registrations → then runApp(). Show a native splash or loading screen during async init.
Full Answer
- ▸ensureInitialized(): Needed before using platform channels in async main
- ▸Initialize Firebase: FirebaseApp.initializeApp(options: DefaultFirebaseOptions.currentPlatform)
- ▸Initialize local DB: await Hive.initFlutter(); await Hive.openBox('settings')
- ▸Register DI: configureDependencies() — GetIt/injectable
- ▸Load critical data: Read user prefs, theme, auth token from secure storage
- ▸runApp(): Only after all the above complete
⚠️
Never do slow async work in widget initState(). Heavy initialization belongs in main(). Widgets should mount with data already available.
Code Examples
dartStructured app initialization
Output
// All services ready before first widget builds // No race conditions or uninitialized service errors
Common Mistakes
- ✗Not awaiting Firebase.initializeApp() — causes PlatformException on first analytics call
- ✗Opening Hive boxes inside widget build() — boxes should be open before runApp()
Interview Tip
💡
Show you know that WidgetsFlutterBinding.ensureInitialized() is required before any async operations in main(). It initializes the Flutter engine's binding to native.
#initialization#async-main#splash-screen#firebase#app-startup