When building a Flutter app, you’ll often need a way to store small pieces of user data — things like theme preferences, login states, or feature toggles. You don’t always need a full database like SQLite or Firebase for that. Instead, Flutter offers a simpler and faster way to store lightweight data locally using SharedPreferences.
In this guide, we’ll walk through how SharedPreferences works, how to set it up, and how to use it effectively to store and retrieve app settings in Flutter.
What Is SharedPreferences in Flutter?
SharedPreferences is a key-value storage system that lets you save small amounts of persistent data on a device. It’s perfect for saving simple settings like:
- Whether dark mode is enabled
- The user’s preferred language
- Login tokens or authentication flags
- App walkthrough or onboarding status
Unlike databases, SharedPreferences doesn’t store complex objects or relationships. It simply keeps basic data types — such as strings, integers, booleans, and doubles — in a fast, lightweight format that persists between app launches.
1. Add the SharedPreferences Package
To start using SharedPreferences, you’ll first need to add its official package to your Flutter project.
Open your project’s pubspec.yaml file and add the following dependency under dependencies:
dependencies:
shared_preferences: ^2.2.0
After saving the file, run the following command in your terminal:
flutter pub get
This downloads the SharedPreferences package and makes it available for use in your project.
2. Import SharedPreferences Into Your Dart File
Once installed, import the package into the file where you plan to use it. Typically, this might be your settings page, login manager, or theme controller.
import 'package:shared_preferences/shared_preferences.dart';
This gives you access to all the methods you’ll need to store and retrieve data.
3. Save Data Using SharedPreferences
SharedPreferences works asynchronously, meaning you’ll need to await most of its functions.
Here’s how you can save a few basic values:
Future<void> saveSettings() async {
final prefs = await SharedPreferences.getInstance();
await prefs.setBool('isDarkMode', true);
await prefs.setString('language', 'en');
await prefs.setInt('fontSize', 16);
}
In this example:
setBoolstores whether dark mode is enabled.setStringstores the user’s preferred language.setIntsaves a custom font size.
These values will persist even if the user closes or restarts the app.
4. Retrieve Stored Data
To load your stored preferences when the app starts, you can use the corresponding get methods.
Here’s an example:
Future<void> loadSettings() async {
final prefs = await SharedPreferences.getInstance();
bool? isDarkMode = prefs.getBool('isDarkMode') ?? false;
String? language = prefs.getString('language') ?? 'en';
int? fontSize = prefs.getInt('fontSize') ?? 14;
print('Dark mode: $isDarkMode, Language: $language, Font size: $fontSize');
}
The ?? operator ensures your app uses a default value if no preference has been saved yet.
You can call this function inside your app’s initialization logic (for example, in initState() of your main screen or a settings controller).
5. Remove or Clear Preferences
Sometimes, you may want to remove a specific setting or clear everything (for example, during logout).
To remove a single preference:
final prefs = await SharedPreferences.getInstance();
await prefs.remove('language');
To clear all stored preferences:
await prefs.clear();
This wipes the entire SharedPreferences file, resetting all stored data to defaults.
6. Example: Storing Theme Settings
Let’s put everything together with a practical example — toggling between light and dark themes using SharedPreferences.
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
final prefs = await SharedPreferences.getInstance();
final isDarkMode = prefs.getBool('isDarkMode') ?? false;
runApp(MyApp(isDarkMode: isDarkMode));
}
class MyApp extends StatefulWidget {
final bool isDarkMode;
const MyApp({super.key, required this.isDarkMode});
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
late bool isDarkMode;
@override
void initState() {
super.initState();
isDarkMode = widget.isDarkMode;
}
Future<void> toggleTheme() async {
final prefs = await SharedPreferences.getInstance();
setState(() {
isDarkMode = !isDarkMode;
});
await prefs.setBool('isDarkMode', isDarkMode);
}
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: isDarkMode ? ThemeData.dark() : ThemeData.light(),
home: Scaffold(
appBar: AppBar(title: const Text('SharedPreferences Example')),
body: Center(
child: SwitchListTile(
title: const Text('Dark Mode'),
value: isDarkMode,
onChanged: (value) => toggleTheme(),
),
),
),
);
}
}
Here’s what happens:
- When the app starts, it checks if dark mode is enabled in SharedPreferences.
- The toggle switch changes the value dynamically and updates the preference.
- When the user reopens the app, it remembers the last selected theme.
It’s a simple yet effective example of how SharedPreferences can make your app feel more personal and user-friendly.
Conclusion
SharedPreferences is one of the easiest ways to store small, persistent data in a Flutter app. It’s ideal for saving user preferences, lightweight configurations, or any information you need to retain across app sessions.
By integrating SharedPreferences into your project, you can make your app more customizable and maintain user choices without the complexity of database systems.
Whether you’re saving dark mode preferences, language settings, or simple app flags — SharedPreferences is a must-have in your Flutter toolkit.