expo-sqlite/kv-store
Set up expo-sqlite/kv-store for storage in an Expo app with ReadyNative: sync + async key/value on SQLite · Expo Go OK
Expo Go: yes
Runs in Expo Go; no dev build needed for this module.
This is the default storage adapter: Expo's SQLite-backed key/value store behind src/lib/storage.ts. I'd keep it unless you have a reason not to - it runs in Expo Go and gives you sync reads on native, so the built-in stores hydrate before first paint. Pick mmkv if you're already on a dev build and want the fastest possible reads, and async-storage only when a library hard-requires it. Whichever one you choose, callers only ever import storage from @/lib/storage; the StorageAdapter interface and createMemoryStorage() for tests live in core src/lib/storage-adapter.ts.
Setup
bun run setup --storage kv-storeThat's it - setup writes src/lib/storage.ts (createKvStoreStorage() plus the active storage) and adds the expo-sqlite dependency and its config plugin through .readynative.json → app.config.ts.
Usage
import { storage } from "@/lib/storage";
await storage.setItem("readynative:draft", JSON.stringify(draft));
const raw = await storage.getItem("readynative:draft");
await storage.removeItem("readynative:draft");
storage.getItemSync?.("readynative:draft"); // native onlyThe built-in stores (src/stores/create-store.ts), zustand persist / Jotai atomWithAppStorage and i18n all go through this adapter, so you rarely call it directly.
Gotchas
- Expo Go works.
getItemSyncis native-only - on web it'sundefined, so always have anawaitpath.- Values are strings; serialize objects yourself (the built-in stores already do).
- Swapping stacks:
bun run setup --storage mmkvor--storage async-storagereplacessrc/lib/storage.tsand nothing else. Keys stay the samereadynative:*strings, but the data lives in a different backend, so existing values do not move - users start fresh on theme mode, onboarding and language. No migration ships.
Remove it
Every app needs a storage option, so there is no none to fall back to - you switch instead. While modules/ exists (a tree set up with --keep-modules), one call does it:
bun run setup --storage mmkv --yes --keep-modulesA finalized tree can't switch: clone a fresh copy of your tier repo, run setup there with the new option and port your code across - see Can I change a module after setup?.
Reference
Everything below is generated from modules/storage/kv-store/module.json - the same file bun run setup reads, so it is what actually lands in your repo.
Install
bun run setup --storage kv-storeModule id: storage/kv-store (the default for this category).
Dependencies
| Package | Version | Kind |
|---|---|---|
expo-sqlite | ~57.0.3 | dependency (expo install) |
Config plugins
Merged into app.config.ts through .readynative.json (modules.app):
expo-sqlite
Privacy
Required-reason APIs: UserDefaults (CA92.1), FileTimestamp (C617.1).
Files
1 files copied to the project root
src/lib/storage.ts