ReadyNative

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-store

That'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 only

The 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.
  • getItemSync is native-only - on web it's undefined, so always have an await path.
  • Values are strings; serialize objects yourself (the built-in stores already do).
  • Swapping stacks: bun run setup --storage mmkv or --storage async-storage replaces src/lib/storage.ts and nothing else. Keys stay the same readynative:* 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-modules

A 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-store

Module id: storage/kv-store (the default for this category).

Dependencies

PackageVersionKind
expo-sqlite~57.0.3dependency (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

On this page

Get ReadyNative