Flutter Switch Theme: Dark Mode Guide with Persistence
Learn how to switch themes in Flutter: ThemeMode wiring, dark colors with ColorScheme.fromSeed, a toggle button, and SharedPreferences persistence.
Dark mode is table stakes now — users expect it, and the OS hands you the signal for free. But most tutorials stop at setting darkTheme on MaterialApp and call it done. A production flutter switch theme implementation needs four more things: runtime switching the user controls, dark colors that actually look designed (not inverted), persistence across restarts, and following the system theme. This guide builds all of it in Flutter 3.x with Material 3: ThemeMode wiring, ColorScheme.fromSeed palettes, a ThemeExtension for brand colors, a toggle button, SharedPreferences persistence, and animated transitions. What you'll learn How theme , darkTheme , and themeMode work together on MaterialApp How the runtime theme-switch flow works end to end How to generate harmonious light and dark palettes with ColorScheme.fromSeed How to add custom brand colors with ThemeExtension How to persist the theme across restarts with SharedPreferences How to follow the system theme with ThemeMode.system How to animate theme transitions Step 0 — Wire theme, darkTheme, and themeMode Every flutter light dark mode setup starts with three properties on MaterialApp : MaterialApp( theme: ThemeData( colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple), useMaterial3: true, ), darkTheme: ThemeData( colorScheme: ColorScheme.fromSeed( seedColor: Colors.deepPurple, brightness: Brightness.dark, ), useMaterial3: true, ), themeMode: ThemeMode.system, // light, dark, or system home: const HomePage(), ); The contract is simple: theme is your light theme, darkTheme is your dark theme, and themeMode picks which one is active. ThemeMode.system follows the OS setting; ThemeMode.light and ThemeMode.dark force one. The single most common dark-mode bug — setting darkTheme but never changing themeMode…