Skip to content

/mobile-storage-mmkv

MMKV high-performance key-value storage for React Native - synchronous JSI-based reads/writes, encryption, typed hooks, multiple instances, listeners, persistence middleware adapters

shell
$ npx -y skills add agents-inc/skills --skill mobile-storage-mmkv --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.
  • You can call itInvoke it directly when you want it.
  • Slash command/mobile-storage-mmkv
How auto-invocation works

Context preview

The summary Claude sees to decide when to auto-load this skill.

MMKV high-performance key-value storage for React Native - synchronous JSI-based reads/writes, encryption, typed hooks, multiple instances, listeners, persistence middleware adapters

SKILL.md

mobile-storage-mmkv.SKILL.md
name: mobile-storage-mmkv
description: MMKV high-performance key-value storage for React Native - synchronous JSI-based reads/writes, encryption, typed hooks, multiple instances, listeners, persistence middleware adapters

MMKV Storage Patterns

> **Quick Guide:** Use `createMMKV()` for synchronous key-value storage (~30x faster than AsyncStorage). One singleton instance per concern (global app, per-user). Use typed hooks (`useMMKVString`, `useMMKVObject`) for reactive components. Enable encryption with `encryptionKey` for sensitive data. V4 is a Nitro Module requiring `react-native-nitro-modules` and React Native 0.75+.

---

<critical_requirements>

CRITICAL: Before Using This Skill

> **All code must follow project conventions in CLAUDE.md** (kebab-case, named exports, import ordering, `import type`, named constants)

**(You MUST reuse a single MMKV instance per concern -- NEVER call `createMMKV()` on every render or in component bodies)**

**(You MUST use typed getters (`getString`, `getNumber`, `getBoolean`) -- NEVER parse the return value of the wrong getter)**

**(You MUST use `remove()` to delete keys -- `delete()` was renamed in v4 due to C++ keyword conflict)**

**(You MUST install `react-native-nitro-modules` alongside `react-native-mmkv` -- v4 is a Nitro Module)**

</critical_requirements>

---

**Auto-detection:** MMKV, react-native-mmkv, createMMKV, useMMKVString, useMMKVNumber, useMMKVBoolean, useMMKVObject, useMMKVBuffer, useMMKVListener, useMMKVKeys, addOnValueChangedListener, encryptionKey, mmkv storage, key-value storage React Native

**When to use:**

  • Persisting user preferences, auth tokens, or cached data synchronously
  • Replacing AsyncStorage for faster reads/writes (~30x improvement)
  • Encrypting sensitive data at rest with AES-128 or AES-256
  • Sharing storage between iOS app and extensions via App Groups
  • Building reactive UIs that re-render on storage changes (hooks)
  • Isolating data per user or feature with multiple named instances

**Key patterns covered:**

  • Instance creation with `createMMKV()` and configuration options
  • Typed getters/setters and object serialization
  • React hooks for reactive storage (`useMMKVString`, `useMMKVObject`, etc.)
  • Value change listeners (`addOnValueChangedListener`, `useMMKVListener`)
  • Multiple instances for data isolation (global vs per-user)
  • Encryption at rest (AES-128/AES-256)
  • Persistence middleware adapter (generic `StateStorage` interface)
  • Migration from AsyncStorage

**When NOT to use:**

  • Large binary files or media (use the filesystem)
  • Relational or queryable data (use a local database)
  • Data that must sync across devices (use a cloud-synced solution)
  • Server state caching with invalidation (use your data fetching layer)

**Detailed Resources:**

  • [examples/core.md](examples/core.md) - Instance setup, typed access, hooks, listeners
  • [examples/advanced.md](examples/advanced.md) - Encryption, multiple instances, App Groups, multi-process, migration
  • [examples/persistence.md](examples/persistence.md) - State management persistence adapter, hydration handling
  • [reference.md](reference.md) - API reference, V3-to-V4 migration table, migration checklist

---

<philosophy>

Philosophy

MMKV is a **synchronous**, JSI-based key-value store built on top of Tencent's battle-tested C++ library. The key advantage over AsyncStorage is that reads and writes are synchronous -- no `await`, no Promises, no bridge serialization. This eliminates an entire class of race conditions and simplifies code.

**Core principles:**

1. **Synchronous by design** -- `getString()` returns immediately, no async wrappers needed 2. **One instance per concern** -- export a singleton; never create instances inside components 3. **Typed access** -- use the correct getter for the stored type; MMKV does not auto-convert 4. **Encrypt sensitive data** -- tokens, keys, PII should use `encryptionKey` option 5. **Hooks for reactivity** -- `useMMKVString` etc. trigger re-renders on changes, replacing manual subscriptions

**Performance comparison with AsyncStorage:**

| Operation | AsyncStorage | MMKV | Speedup | |----------------|-------------|--------|---------| | Read 1 key | ~5ms | ~0.015ms | ~300x | | Write 1 key | ~8ms | ~0.018ms | ~440x | | Read 1000 keys | ~200ms | ~3ms | ~65x |

Benchmarks vary by device, but MMKV is consistently 30-100x faster for typical operations.

**V4 architecture:** MMKV v4 is a Nitro Module (not a TurboModule). This means it uses `react-native-nitro-modules` for the native bridge, requires React Native 0.75+, and the JS API uses `createMMKV()` instead of `new MMKV()`.

</philosophy>

---

<patterns>

Core Patterns

Pattern 1: Instance Creation and Singleton Export

Create one instance per storage concern at module scope. Never inside a component or hook body.

import { createMMKV } from "react-native-mmkv";

// Global app storage -- reuse this everywhere
export const storage = createMMKV();

// Named instance for user-specific data
export const createUserStorage = (userId: string) =>
  createMMKV({ id: `user-${userId}` });

**Why good:** Module-level creation runs once, all consumers share the same native instance, no wasted allocations

// BAD: Creating instance inside component
function Settings() {
  const storage = createMMKV(); // New native instance every render
  // ...
}

**Why bad:** Creates a new native MMKV instance on every render, wastes memory, defeats instance caching

See [examples/core.md](examples/core.md) for full configuration options (path, encryption, readOnly, compareBeforeSet).

---

Pattern 2: Typed Getters and Setters

MMKV stores values by type. Always use the matching getter for what was stored.

// Set typed values
storage.set("user.name", "Alice");
storage.set("user.age", 28);
storage.set("onboarded", true);

// Get with correct typed getter
const name = storage.getStr
Read more
Read it on GitHub ↗

Showing the first part of this file.

Ships withagents-inc-skills

The official skills marketplace for Agents Inc. 150+ skills covering everything from React and Prisma to Redis, ElevenLabs, and infrastructure tooling. Pick the skills that match your stack and install them via Claude Code. Need more control?

Get the whole plugin, auto-invoked