AsyncStorage
Set up AsyncStorage for storage in an Expo app with ReadyNative: async-only key/value, the community standard · Expo Go OK
Expo Go: yes
Runs in Expo Go; no dev build needed for this module.
AsyncStorage is the community-standard async key/value store (@react-native-async-storage/async-storage), behind the same src/lib/storage.ts. I'd pick it for one reason: a library you depend on hard-requires AsyncStorage - some auth and analytics SDKs take it as a storage option, and this way you keep a single store. Otherwise prefer kv-store (Expo Go and sync reads on native) or mmkv (fastest, dev build). Callers don't change: they import storage from @/lib/storage.
Setup
bun run setup --storage async-storageThat's it - setup writes src/lib/storage.ts (createAsyncStorageStorage() plus the active storage, with no *Sync methods), adds @react-native-async-storage/async-storage 2.2.0 (the SDK 57 pin), a jest stand-in under __mocks__/ that re-exports the package's own jest/async-storage-mock, and an adapter test. There's no config plugin.
Usage
import { storage } from "@/lib/storage";
await storage.setItem("readynative:draft", JSON.stringify(draft));
const raw = await storage.getItem("readynative:draft");
storage.getItemSync; // undefined - always await getItem()If a SDK wants the raw module, pass AsyncStorage straight in; it's the same store your adapter writes to.
Gotchas
- Expo Go and web both work.
- There's no sync API, so the built-in stores, zustand
persistand i18n all hydrate asynchronously: gate first paint onstore.useHydrated()or the splash screen, and remember the initial language is only known afterinitI18n()resolves. - Values are strings only -
setItemwith a non-string throws in the native module, so serialize first (the built-in stores already do). - Android has a 6 MB total-size default; raise it with
AsyncStorage_db_size_in_MBingradle.propertiesif you store more. - Swapping stacks:
bun run setup --storage kv-store|mmkvreplacessrc/lib/storage.ts. Keys stay the samereadynative:*strings but the data lives in a different backend, so existing values do not move - users start fresh. 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 kv-store --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/async-storage/module.json - the same file bun run setup reads, so it is what actually lands in your repo.
Install
bun run setup --storage async-storageModule id: storage/async-storage.
Dependencies
| Package | Version | Kind |
|---|---|---|
@react-native-async-storage/async-storage | 2.2.0 | dependency (expo install) |
Privacy
Required-reason APIs: UserDefaults (CA92.1), FileTimestamp (C617.1).
Files
3 files copied to the project root
__mocks__/@react-native-async-storage/async-storage.tssrc/lib/__tests__/storage-async-storage.test.tssrc/lib/storage.ts