# selfstore vs raw IndexedDB Source: https://selfstore.dev/compare/indexeddb IndexedDB is the right engine and a hostile API - what you would build on top of it, and what selfstore already built. ## Respect where due IndexedDB is the correct storage engine in every browser: asynchronous, transactional, structured-clone-native (real binary data, no base64), gigabyte-capable. selfstore's working copy **is** IndexedDB. This page is not IndexedDB versus something else; it is raw usage versus a loop built on it. ## What raw IndexedDB hands you An API from 2010 with events instead of promises, version-upgrade callbacks that brick your app when mishandled, transactions that auto-commit under you, and absolutely nothing above the engine: no backup format, no encryption, no sync, no status, no multi-tab discipline. Every team that ships on raw IDB ends up writing the same five hundred lines, then debugging them in production. ## The layer selfstore adds | Concern | Raw IndexedDB | selfstore | | --- | --- | --- | | API | Event-based, version upgrades | Two functions: gather() and apply() | | Backup | Build your own format | Spec'd encrypted ZIP, one fluent call | | Encryption | DIY WebCrypto | AES-256-GCM + Argon2id, in a worker | | Sync | None | Deterministic HLC merge, five strategies | | Multi-tab | DIY locks | Web Lock + BroadcastChannel, built in | | Schema evolution | onupgradeneeded | schemaVersion + migrate(), SCHEMA_TOO_NEW guard | | Status for the UI | None | Headless descriptor | ## Use raw IndexedDB (or a query wrapper) when - You have a **large, queryable dataset**: tens of thousands of records, indexes, cursors, range scans. selfstore's snapshot model is deliberately whole-state and memory-bound; it is not a query engine. (For that need, also look at [Dexie](https://selfstore.dev/compare/dexie), which we recommend without irony.) ## Use selfstore when - The job is "persist my app's state, durably, privately, portably", not "query a million rows". - You want the user to hold a real backup file, and maybe open the same data on a second device, without operating servers. The two coexist fine: keep a big Dexie/IDB dataset for querying, and let selfstore own the app-state loop next to it. Map of this site for a model: https://selfstore.dev/llms.txt Every page in one file: https://selfstore.dev/llms-full.txt