How To Use Shared Preferences for Local Storage
Jan 14, 2026



Summary
Summary
Summary
Summary
A concise guide to using shared_preferences in Flutter for small, persistent key-value storage. Covers installation, basic read/write patterns, testing, migrations, performance and security considerations.
A concise guide to using shared_preferences in Flutter for small, persistent key-value storage. Covers installation, basic read/write patterns, testing, migrations, performance and security considerations.
A concise guide to using shared_preferences in Flutter for small, persistent key-value storage. Covers installation, basic read/write patterns, testing, migrations, performance and security considerations.
A concise guide to using shared_preferences in Flutter for small, persistent key-value storage. Covers installation, basic read/write patterns, testing, migrations, performance and security considerations.
Key insights:
Key insights:
Key insights:
Key insights:
Installing The Package: Add shared_preferences to pubspec.yaml and run flutter pub get; it works on Android, iOS, and web out of the box.
Basic Usage And Types: Use getInstance(), then typed getters/setters for int, double, bool, String, and List; await setX calls to ensure persistence.
Best Practices And Limitations: Ideal for small settings and flags; not for large datasets—use databases for complex or large data.
Performance And Concurrency: Cache the SharedPreferences instance, avoid repeated getInstance() calls, and await writes when necessary.
Security And Testing: Do not store secrets in plaintext; use secure storage for sensitive data and SharedPreferences.setMockInitialValues for tests.
Introduction
Shared Preferences is a simple key-value storage API for small pieces of data such as user settings, flags, or last-opened screens. In Flutter mobile development, it's the go-to choice for persisting primitive values without the overhead of a database. This tutorial shows how to install, initialize, read, write, and apply best practices when using Shared Preferences in your Flutter apps.
Installing The Package
Add the official shared_preferences package to your pubspec.yaml. This package provides a platform-native implementation on Android and iOS and falls back gracefully on other platforms supported by Flutter.
In pubspec.yaml:
dependencies: flutter: sdk: flutter shared_preferences
Run flutter pub get. No additional native configuration is normally required for Android or iOS—the package handles platform channels for you. For web, the package stores values in browser local storage.
Basic Usage And Types
Shared Preferences stores primitive types: int, double, bool, String, and List. You obtain a SharedPreferences instance asynchronously and then read or write using typed getters and setters. Prefer caching the instance in a long-lived service or provider rather than calling getInstance() repeatedly.
Example: initialize, write, and read a boolean flag and a string.
import 'package:shared_preferences/shared_preferences.dart'; Future<void> saveLogin(bool loggedIn, String username) async { final prefs = await SharedPreferences.getInstance(); await prefs.setBool('loggedIn', loggedIn); await prefs.setString('username', username); } Future<Map<String, dynamic>> loadLogin() async { final prefs = await SharedPreferences.getInstance(); return { 'loggedIn': prefs.getBool('loggedIn') ?? false, 'username': prefs.getString('username') ?? '' }; }
Notes:
setX methods return Future to indicate success. Always await if subsequent logic depends on persistence completing.
Use clear, unique keys. Prefer scoped keys (e.g., "user.username") to avoid collisions.
List is supported; other collection types must be serialized, typically to JSON stored as a String.
Best Practices And Limitations
Where to use Shared Preferences:
Small configuration values, toggles, theme selection, last visited route, onboarding-complete flag.
Not suitable for large datasets, binary assets, or complex queries. For anything relational or large, use a database (sqflite, drift) or file storage.
Performance and concurrency:
SharedPreferences uses platform storage APIs that are fast for small reads/writes, but repeated synchronous-style calls can create overhead. Always await writes when necessary.
Avoid calling getInstance() inside tight loops—get it once and reuse.
Data modeling and migration:
Treat the storage as versioned: include a schema version key (e.g., "prefs_version") and write migration code when your app changes how it structures persisted keys.
When changing a value type, provide a fallback and migration path. Example: if you change a setting from bool to int, read the old key and convert, then write the new key and remove the old one.
Security considerations:
Shared Preferences are not encrypted by default. Do not store secrets (passwords, tokens) in plain text. For secure storage use flutter_secure_storage or platform-level secure keystores.
Testing tips:
In unit tests, use dependency injection to provide a mock or an in-memory wrapper around SharedPreferences. The package provides a method to set mock values in tests: SharedPreferences.setMockInitialValues({}).
Example: set mock prefs in a test setup:
// In test setup SharedPreferences.setMockInitialValues({'theme': 'dark'}); final prefs = await SharedPreferences.getInstance(); expect(prefs.getString('theme'), 'dark');
Vibe Studio

Vibe Studio, powered by Steve’s advanced AI agents, is a revolutionary no-code, conversational platform that empowers users to quickly and efficiently create full-stack Flutter applications integrated seamlessly with Firebase backend services. Ideal for solo founders, startups, and agile engineering teams, Vibe Studio allows users to visually manage and deploy Flutter apps, greatly accelerating the development process. The intuitive conversational interface simplifies complex development tasks, making app creation accessible even for non-coders.
Conclusion
Shared Preferences is an essential tool in Flutter mobile development for lightweight, synchronous-like local storage of primitive values. Use it for settings, feature flags, and small state persistence. Remember to cache the instance, handle migrations, avoid storing secrets, and move to databases or secure storage when needs exceed its scope. With these practices you'll keep your app responsive and maintainable when persisting local state.
Introduction
Shared Preferences is a simple key-value storage API for small pieces of data such as user settings, flags, or last-opened screens. In Flutter mobile development, it's the go-to choice for persisting primitive values without the overhead of a database. This tutorial shows how to install, initialize, read, write, and apply best practices when using Shared Preferences in your Flutter apps.
Installing The Package
Add the official shared_preferences package to your pubspec.yaml. This package provides a platform-native implementation on Android and iOS and falls back gracefully on other platforms supported by Flutter.
In pubspec.yaml:
dependencies: flutter: sdk: flutter shared_preferences
Run flutter pub get. No additional native configuration is normally required for Android or iOS—the package handles platform channels for you. For web, the package stores values in browser local storage.
Basic Usage And Types
Shared Preferences stores primitive types: int, double, bool, String, and List. You obtain a SharedPreferences instance asynchronously and then read or write using typed getters and setters. Prefer caching the instance in a long-lived service or provider rather than calling getInstance() repeatedly.
Example: initialize, write, and read a boolean flag and a string.
import 'package:shared_preferences/shared_preferences.dart'; Future<void> saveLogin(bool loggedIn, String username) async { final prefs = await SharedPreferences.getInstance(); await prefs.setBool('loggedIn', loggedIn); await prefs.setString('username', username); } Future<Map<String, dynamic>> loadLogin() async { final prefs = await SharedPreferences.getInstance(); return { 'loggedIn': prefs.getBool('loggedIn') ?? false, 'username': prefs.getString('username') ?? '' }; }
Notes:
setX methods return Future to indicate success. Always await if subsequent logic depends on persistence completing.
Use clear, unique keys. Prefer scoped keys (e.g., "user.username") to avoid collisions.
List is supported; other collection types must be serialized, typically to JSON stored as a String.
Best Practices And Limitations
Where to use Shared Preferences:
Small configuration values, toggles, theme selection, last visited route, onboarding-complete flag.
Not suitable for large datasets, binary assets, or complex queries. For anything relational or large, use a database (sqflite, drift) or file storage.
Performance and concurrency:
SharedPreferences uses platform storage APIs that are fast for small reads/writes, but repeated synchronous-style calls can create overhead. Always await writes when necessary.
Avoid calling getInstance() inside tight loops—get it once and reuse.
Data modeling and migration:
Treat the storage as versioned: include a schema version key (e.g., "prefs_version") and write migration code when your app changes how it structures persisted keys.
When changing a value type, provide a fallback and migration path. Example: if you change a setting from bool to int, read the old key and convert, then write the new key and remove the old one.
Security considerations:
Shared Preferences are not encrypted by default. Do not store secrets (passwords, tokens) in plain text. For secure storage use flutter_secure_storage or platform-level secure keystores.
Testing tips:
In unit tests, use dependency injection to provide a mock or an in-memory wrapper around SharedPreferences. The package provides a method to set mock values in tests: SharedPreferences.setMockInitialValues({}).
Example: set mock prefs in a test setup:
// In test setup SharedPreferences.setMockInitialValues({'theme': 'dark'}); final prefs = await SharedPreferences.getInstance(); expect(prefs.getString('theme'), 'dark');
Vibe Studio

Vibe Studio, powered by Steve’s advanced AI agents, is a revolutionary no-code, conversational platform that empowers users to quickly and efficiently create full-stack Flutter applications integrated seamlessly with Firebase backend services. Ideal for solo founders, startups, and agile engineering teams, Vibe Studio allows users to visually manage and deploy Flutter apps, greatly accelerating the development process. The intuitive conversational interface simplifies complex development tasks, making app creation accessible even for non-coders.
Conclusion
Shared Preferences is an essential tool in Flutter mobile development for lightweight, synchronous-like local storage of primitive values. Use it for settings, feature flags, and small state persistence. Remember to cache the instance, handle migrations, avoid storing secrets, and move to databases or secure storage when needs exceed its scope. With these practices you'll keep your app responsive and maintainable when persisting local state.
Build Flutter Apps Faster with Vibe Studio
Vibe Studio is your AI-powered Flutter development companion. Skip boilerplate, build in real-time, and deploy without hassle. Start creating apps at lightning speed with zero setup.
Other Insights






















