selfstore vs localStorage
TL;DR: localStorage is fine for a theme flag. The moment users would be upset to lose the data, it is the wrong tool.
What localStorage is great at
Being there. Zero install, synchronous, universally supported, perfect for a theme preference, a dismissed-banner flag, a last-used tab. For sub-kilobyte convenience state, reaching for anything heavier is over-engineering, and we will happily tell you so.
Where it stops
- Strings only, ~5 MB, synchronous. Structured data means JSON.parse on the main thread; binary files mean base64 bloat; the quota is small and inconsistently enforced.
- No durability story. “Clear site data”, a panicked cache wipe, a new device, a lost laptop: the data is simply gone. There is no backup, no export, no sync.
- No integrity. Two tabs race each other, and a half-written JSON string is your problem to detect.
What selfstore changes
selfstore is a storage loop, not a key-value shim: an IndexedDB working copy saved on every change, real encrypted ZIP backups the user can hold, durable homes (disk, Google Drive, WebDAV, S3), and deterministic multi-device sync. Tabs coordinate through a Web Lock instead of racing.
| localStorage | selfstore | |
|---|---|---|
| Data model | Strings | Named JSON collections + binary files |
| Capacity | ~5 MB | IndexedDB-scale (MB by design) |
| Survives cleared site data | No | Yes, via a durable home |
| Backup file for the user | None | Encrypted ZIP, open format |
| Multi-device | No | Deterministic serverless merge |
| Multi-tab | Races | Coordinated (Web Lock + BroadcastChannel) |
| Bundle size | None, built into the browser | ~23 KB gzip |
Use localStorage when
- The value is a preference you could lose without apologizing to anyone.
- You need synchronous read-at-boot (a theme class before first paint).
Use selfstore when
- Users type things they expect to still exist next month.
- “Export my data” or “works on my other laptop” is on your roadmap.
- You are one
JSON.parse(localStorage.getItem(...))away from writing a storage layer by hand. That layer is the library.