zustand-mmkv-storage: Blazing Fast Persistence for Zustand in React Native
Source: Dev.to
Why Do We Need Persistent State in React Native?
Mobile users expect apps to “remember” them:
- Login tokens should stay valid
- Shopping carts shouldn’t empty on app close
- Theme preferences (dark/light) should persist
- Onboarding flow shouldn’t replay every time
Without persistence, your app feels broken. With good persistence, it feels native and polished.
The Old King: AsyncStorage
For years, AsyncStorage was the default solution. It’s simple, works everywhere, and integrates nicely with libraries like Zustand/Redux.
But it has serious downsides:
- Slow: Fully JavaScript‑based, serialized bridge calls
- Async‑only: Every read/write blocks UI if not careful
- No encryption out of the box
- Deprecated by the React Native core team (replaced by community forks)
Benchmarks show MMKV can be 30–100× faster than AsyncStorage in real‑world scenarios.
Enter MMKV: The Modern Champion
MMKV (Mobile Key‑Value) is a high‑performance key‑value store developed by Tencent and now maintained by Marc Rousavy.
Key advantages:
- Written in C++ with JSI bindings → blazing fast
- Synchronous reads/writes (no
awaitneeded forget) - Built‑in encryption support
- Multi‑process mode (safe for app groups/extensions)
- Tiny footprint, Expo‑compatible
- Actively maintained and used in production by large apps
In short: MMKV is what AsyncStorage should have been in 2025.
Zustand + Persistence = Magic
Zustand is the most popular lightweight state manager in React Native today. Its persist middleware makes saving state trivial — if you have a good storage backend.
That’s where most people hit friction: wiring MMKV manually is verbose, error‑prone, and doesn’t handle instance sharing or encryption cleanly.
Introducing zustand-mmkv-storage
I built zustand-mmkv-storage to solve exactly this.
It’s a tiny wrapper that lets you plug MMKV into Zustand’s persist middleware with minimal boilerplate:
import { create } from 'zustand';
import { persist, createJSONStorage } from 'zustand/middleware';
import { mmkvStorage } from 'zustand-mmkv-storage';
export const useBearStore = create(
persist(
(set) => ({
bears: 0,
addBear: () => set((state) => ({ bears: state.bears + 1 })),
}),
{
name: 'bear-storage', // key in MMKV
storage: createJSONStorage(() => mmkvStorage),
}
)
);
Your bears count now persists across app restarts — fast and reliably.
Advanced: Encrypted & Isolated Storage
import { createMMKVStorage } from 'zustand-mmkv-storage';
const secureStorage = createMMKVStorage({
id: 'secure-vault', // separate file
encryptionKey: 'my-secret-2025', // enables encryption
});
export const useAuthStore = create(
persist(
(set) => ({
token: '',
setToken: (token) => set({ token }),
}),
{
name: 'auth-storage',
storage: createJSONStorage(() => secureStorage),
}
)
);
Now your auth token is encrypted on disk and completely isolated from other data.
Use Cases
- Auth tokens & refresh tokens
- User preferences (theme, language)
- Shopping carts / offline forms
- Onboarding completion
- Feature flags / A‑B testing
Try It Today!
npm i zustand-mmkv-storage
If this saves you time or makes your app faster, I’d love a ⭐ on GitHub!
Thanks for reading — happy (and fast) persisting! 🐻✨