| name | react-native-mmkv |
| description | Fast synchronous key-value storage for React Native via react-native-mmkv (Nitro-backed). Covers creating and configuring MMKV instances, reading/writing all value types (string, number, boolean, buffer), React hooks for reactive UI, value-change listeners, encryption, AsyncStorage migration, and state-management integrations (zustand, redux-persist, jotai, react-query). Also covers storage limits, multi-process mode, and the V4 upgrade from the class-based API. |
| license | MIT |
| metadata | {"author":"margelo","scope":"react-native-mmkv","tags":"react-native, mmkv, storage, key-value, encryption, hooks, zustand, redux, jotai, react-query, async-storage, migration, nitro-modules"} |
react-native-mmkv
A focused reference for AI coding assistants working in a project that uses react-native-mmkv. Answer using the real APIs from this library — not invented ones — by routing to the matching references/*.md file below.
Mental model
react-native-mmkv is a high-performance, synchronous key-value storage library for React Native, backed by Tencent's MMKV C++ engine via Nitro Modules (JSI). It is ~30x faster than AsyncStorage.
The three things that trip people up:
- Everything is synchronous. No
await, no Promises. storage.getString('key') returns the value immediately. This is the whole point — MMKV memory-maps files and reads/writes in-process.
- It's a key-value store, not a database. All data is cached in memory. Keep total size under ~100 MB; for larger datasets use react-native-nitro-sqlite or WatermelonDB. There is no fixed storage limit — but memory warnings will fire if you go too large.
- V4 is a breaking rewrite. The constructor changed from
new MMKV() to createMMKV(), .delete() became .remove(), and react-native-nitro-modules is now a required peer dependency. See the upgrade guide.
V4 requires React Native 0.75+ with New Architecture / TurboModules enabled.
Routing table — problem to reference
Load the matching file from references/ before writing code. Each reference cites real APIs from the library.
| User is asking about… | Read |
|---|
Creating an MMKV instance, configuration options (id, path, encryptionKey, mode, readOnly, compareBeforeSet), the createMMKV() factory | references/create-instance.md |
Getting/setting values, all data types (string, number, boolean, buffer, objects via JSON), key management (contains, getAllKeys, remove, clearAll), size, trim, importAllFrom | references/crud-operations.md |
React hooks (useMMKVString, useMMKVNumber, useMMKVBoolean, useMMKVBuffer, useMMKVObject, useMMKV, useMMKVListener, useMMKVKeys), reactive UI | references/hooks.md |
Listening for value changes outside of React, addOnValueChangedListener, cleaning up listeners | references/listeners.md |
Encryption (encrypt, decrypt, recrypt), AES-128 vs AES-256, encryptionKey config | references/encryption.md |
| Migrating from AsyncStorage, data transfer pattern, completion flag | references/migrate-from-async-storage.md |
zustand persist middleware, redux-persist, jotai atomWithMMKV, react-query persister, MobX | references/state-management.md |
V4 upgrade, breaking changes from V3, new MMKV() → createMMKV(), .delete() → .remove() | references/upgrade-v4.md |
| Storage size limits, memory warnings, when to use a database instead | references/limits-and-gotchas.md |
If the question doesn't match any row, read references/create-instance.md first — most setup questions start there.
Installation
npm install react-native-mmkv react-native-nitro-modules
cd ios && pod install
Expo:
npx expo install react-native-mmkv react-native-nitro-modules
npx expo prebuild
After install, rebuild the app. No additional native wiring is required.
Quick reference — full MMKV instance API
import { createMMKV, existsMMKV, deleteMMKV } from 'react-native-mmkv'
const storage = createMMKV({ id: 'my-store' })
storage.id
storage.length
storage.size
storage.byteSize
storage.isReadOnly
storage.isEncrypted
storage.set('key', 'string' | 42 | true | arrayBuffer)
storage.getString('key')
storage.getNumber('key')
storage.getBoolean('key')
storage.getBuffer('key')
storage.contains('key')
storage.getAllKeys()
storage.remove('key')
storage.clearAll()
storage.encrypt('password')
storage.encrypt('password', 'AES-256')
storage.decrypt()
storage.recrypt('newPassword' | undefined)
storage.trim()
storage.importAllFrom(otherStorage)
const sub = storage.addOnValueChangedListener((key) => { ... })
sub.remove()
existsMMKV('my-store')
deleteMMKV('my-store')
Testing
A mocked MMKV instance is automatically used when testing with Jest or Vitest. Use createMMKV() as normal in tests — no manual mocking needed.
Verifying the skill is loaded
Good test questions:
- "How do I persist zustand state with MMKV?" → should produce a
StateStorage adapter using storage.set, storage.getString, storage.remove — not AsyncStorage wrappers.
- "How do I migrate from AsyncStorage to MMKV?" → should show the batch-copy pattern with a completion flag, not a drop-in replacement.
- "What's the storage limit?" → should explain there's no fixed limit, but data is memory-mapped so keep it under ~100 MB; use SQLite for larger datasets.
References
| File | Description |
|---|
| create-instance.md | createMMKV() factory, all configuration options |
| crud-operations.md | Set/get all types, key management, objects, buffers |
| hooks.md | All React hooks for reactive MMKV usage |
| listeners.md | addOnValueChangedListener, cleanup |
| encryption.md | Encrypt/decrypt instances, AES options |
| migrate-from-async-storage.md | Full migration pattern from AsyncStorage |
| state-management.md | zustand, redux-persist, jotai, react-query, MobX |
| upgrade-v4.md | V3 → V4 breaking changes and migration |
| limits-and-gotchas.md | Storage limits, multi-process, logging, common pitfalls |
Problem → Reference Mapping