5 min read
Data Persistence
Apps that remember things need to store data somewhere. This guide covers the options and when to use each.
Do You Need Persistence?
Yes, if:
- User creates content (notes, projects, settings)
- App should remember state between sessions
- Data needs to sync across devices
- Multiple users share data
No, if:
- App is a stateless tool
- User starts fresh each time
- No personalization needed
Local Storage Options
Web: localStorage
Simple key-value storage in the browser.
Save the user's preferences to localStorage.
Load them when the app starts.
Good for:
- User preferences
- Draft content
- UI state (sidebar open/closed)
Limitations:
- 5MB limit
- Only strings (JSON.stringify for objects)
- Cleared if user clears browser data
macOS: UserDefaults
Apple’s built-in preferences system.
Save the user's settings to UserDefaults.
Load them when the app launches.
Good for:
- App preferences
- Simple data
- Settings that should persist
iOS: Same as macOS
UserDefaults works the same way.
All platforms: File system
Save data as files.
Save the document to a file.
Let the user choose the save location.
When to Use a Database
Signs you need one:
- Multiple users with their own data
- Data needs to sync across devices
- Complex queries or relationships
- Data is larger than a few MB
Types of databases:
Relational (SQL)
- Structured data in tables
- PostgreSQL, MySQL, SQLite
- Good for: structured, related data
Document (NoSQL)
- Flexible JSON-like documents
- MongoDB, Firestore
- Good for: varied data shapes
Key-value
- Simple key → value lookup
- Redis
- Good for: caching, sessions
Easy Database Options
Supabase
PostgreSQL with a nice interface.
Set up Supabase for this project.
Create a table for [data type].
Add functions to read and write [data].
Includes:
- Database
- Authentication
- Real-time subscriptions
- File storage
Firebase Firestore
Google’s document database.
Set up Firestore for this project.
Create a collection for [data type].
Includes:
- NoSQL database
- Real-time sync
- Offline support
- Authentication
PlanetScale
Serverless MySQL.
Set up PlanetScale for this project.
Choosing Storage
| Need | Recommendation |
|---|---|
| User preferences | localStorage / UserDefaults |
| Draft content | localStorage with auto-save |
| User accounts + data | Supabase or Firebase |
| Real-time sync | Firebase or Supabase real-time |
| Large files | Cloud storage (S3, Cloudflare R2) |
| Simple notes app | Start local, add cloud later |
Data Patterns
Loading data on app start
When the app starts, load the user's [data] from [storage].
Show a loading state while fetching.
Saving on change
Auto-save [content] whenever it changes.
Show a "Saving..." indicator briefly.
Syncing across devices
Sync the user's [data] across devices using [Supabase/Firebase].
Handle conflicts by using the most recent change.
Offline support
Cache [data] locally so the app works offline.
Sync changes when connection is restored.
CRUD Operations
Create
Add a form to create new [items].
Save to [storage] when submitted.
Read
Load all [items] and display them in a list.
Show loading state while fetching.
Update
Allow editing [items].
Save changes to [storage].
Delete
Add delete functionality with confirmation.
Remove from [storage] when confirmed.
Data Structure
Planning your data
Before implementing, think about:
- What data do you need to store?
- How are pieces related?
- What queries will you run?
Example: Notes app
Data structure for notes:
- Note: id, title, content, createdAt, updatedAt, userId
- Users have many notes
- Notes belong to one user
Example: Task manager
Data structure for tasks:
- Task: id, title, completed, dueDate, projectId, userId
- Project: id, name, userId
- Users have many projects
- Projects have many tasks
Debugging Data Issues
Data not saving
Changes aren't being saved to [storage].
Here's what I'm trying: [describe]
Here's the error: [paste if any]
Data not loading
The app starts but data doesn't load.
[Describe what happens]
Sync issues
Data on one device isn't showing on another.
[Describe the sync setup]
See Also
If your app fetches data from external services, the APIs guide covers how to pull in live data. And if you’re wondering about the difference between temporary state and saved data, the State guide explains how in-memory state works before you persist it.
Key Takeaways
- When you need data persistence
- Local storage options by platform
- When to use a database
- Easy database services
- Common data patterns
- CRUD operations