Local Data Options
Choose storage by durability, query needs, target platforms, privacy, and migration cost.
Decision Table
| Need | Start with | Watch for |
|---|---|---|
| Tiny preferences | shared_preferences | Primitive types only, not guaranteed durable enough for critical data |
| User files or exports | path_provider plus dart:io | Not the same recipe on web |
| Relational local data on Android/iOS/macOS | sqflite | Recipe support does not cover every desktop/web target |
| Cross-platform relational app data | Evaluate Drift/sqlite3/FFI/Web options | Platform-specific setup and migrations |
| Sensitive data | Secure storage plus encrypted backup design | Key recovery and platform secure-store differences |
| Offline-first sync | Local source of truth plus mutation queue | Conflict rules, idempotency, observability |
Recommended Stance
Use a separate decision matrix instead of one universal default. For small settings, use key-value storage. For real app records, use a database. For web parity, verify the storage package’s web implementation before committing.
Questions Before Choosing
- Does the app need queryable records or just preferences?
- Must data survive uninstall, migration, export, or backup?
- Is web a first-class target?
- Does the data need encryption at rest?
- Will the app sync later, or is export/import enough?
Gotcha: Local storage choices become product choices. Backup, export, restore, migration, and account recovery matter more than which package is fashionable.