Hey, I'm Ekaksh.
In this post I'm going to walk you through how I set up dark mode and light mode in Flutter using nothing besides ValueNotifier and ValueListenableBuilder.
This is exactly the same setup I showed in my YouTube video.
I use this pattern in basically every Flutter app I build because it's clean, simple, and works everywhere in the app without dragging in state-management packages just for toggling a theme.
Let's jump into it.
Step 1: Create a new project and install dependencies (optional)
Create a new Flutter project:
Add shared_preferences if you want to persist the theme choice:
Now, just remove the boilerplate from main.dart, create your usual app.dart and home.dart, and get a basic MaterialApp running.
Setp 2: Create the Theme Notifier (this is the core)
We need something to tell the entire app:
"Theme mode changed — rebuild yourself."
Flutter already gives us ValueNotifier, so we'll just use that.
So, let's create a theme_notifier.dart file and write the following code:
Why a singleton? Because I want to access this from anywhere in the app without passing BuildContext around like it’s hot potato.
Step 3: Persisting the theme with SharedPreferences (optional)
If someone switches to dark mode, closes the app, opens it again — the app should stay in dark mode.
For this, we can use the shared_preferences package we added earlier.
Let's create a class called LocalStorage in a file called local_storage.dart to handle saving and retrieving things from local storage:
Step 4: Complete the theme notifier with persistence
Now let's complete the theme notifier by implementing the loadThemeMode, saveThemeMode, and toggleTheme methods:
Step 5: Setup the material app to listen to theme changes
In your app.dart, wrap your MaterialApp with a ValueListenableBuilder that listens to the themeModeNotifier:
Finally in your main.dart, initialize the LocalStorage and loadThemeMode before running the app:
Step 6: Setup your home.dart
Great! Now we have a working dark mode and light mode toggle, with persistence using local storage and zero external state-management packages. Just simple ValueNotifiers doing their job.
Here is the full source code:
Theme Notifier Tutorial
Thanks for reading, hope this helps you keep your theming clean.