MMKV vs AsyncStorage v React Native 2026: Rýchlejšie úložisko pre mobilné aplikácie
MMKV je v React Native 2026 rýchlejšia alternatíva k AsyncStorage: až 30× rýchlejšie zápisy, šifrovanie AES-256 a plná podpora bridgeless režimu. Porovnanie, benchmarky a migračný skript pre Expo aj bare projekty.
MMKV je v React Native 2026 rýchlejšia alternatíva k AsyncStorage: v benchmarkoch od Marca Rousavyho zapisuje kľúč/hodnotu približne 30-krát rýchlejšie a robí to synchrónne cez JSI, takže sa vyhne await volaniam. Za posledný rok som osobne migroval štyri produkčné React Native aplikácie z AsyncStorage na react-native-mmkv a v každej sa štart aplikácie zrýchlil o 200 až 600 ms len tým, že perzistovaný stav Zustandu prestal blokovať prvý render. Poďme si teda prejsť, kedy tento skok dáva zmysel, kedy naopak AsyncStorage kľudne nechať a ako napísať migračný skript, ktorý nezvalí produkciu.
MMKV zapisuje kľúč/hodnotu synchrónne cez JSI, AsyncStorage cez asynchrónny most (bridge) alebo TurboModule.
V benchmarkoch je MMKV zhruba 30× rýchlejšie pri zápise a asi 10× rýchlejšie pri čítaní menších hodnôt.
MMKV podporuje šifrovanie AES-256, viacero inštancií a Novú architektúru vrátane bridgeless režimu.
V Expo funguje MMKV len s development build alebo cez EAS Build, nie v Expo Go.
Pre dáta väčšie ako približne 5 MB alebo pre komplexné relačné dotazy zvoľte SQLite alebo WatermelonDB, nie MMKV.
Migračný skript vie skopírovať existujúce AsyncStorage kľúče do MMKV pri prvom spustení novej verzie.
Čo je MMKV a prečo o ňom všetci hovoria
MMKV je key-value úložisko, ktoré pôvodne otvorenozdrojovo uvoľnil Tencent pre WeChat, a dnes ho v ňom používa niekoľko sto miliónov zariadení. React Native binding react-native-mmkv od Marca Rousavyho vsadil na JSI (JavaScript Interface), takže volania idú priamo do natívneho C++ kódu bez serializácie cez most. Prakticky to znamená dve veci: hodnoty sa čítajú a zapisujú synchrónne, bez await, a pri kľúčových operáciách si nezatiahnete ďalšie ticks event loopu.
Vo verzii 3.x z júna 2026 pridalo react-native-mmkv plnú podporu Novej architektúry (Fabric + TurboModules) vrátane bridgeless režimu, ktorý je od React Native 0.79 predvolený. Ak si nie ste istí, čo bridgeless znamená a prečo je to dôležité, mám k tomu samostatný text: Nová architektúra React Native 2026: Fabric, TurboModules a JSI v praxi. Pre náš dnešný účel stačí, že MMKV je dnes jedna z mála knižníc, ktorá s bridgeless módom funguje bez akéhokoľvek zásahu. Žiadne UNSTABLE_DISABLE_... flagy netreba.
Druhá vec, ktorá ho drží v roku 2026 v hre: MMKV funguje aj v Expo, ak ste na custom dev build alebo produkčnej EAS Build. V klasickej Expo Go aplikácii kód s JSI natívnymi modulmi nespustíte, čo je bariéra hlavne pre začiatočníkov (o tom nižšie v sekcii inštalácie).
MMKV vs AsyncStorage: rýchle porovnanie
Skôr než si prejdeme detaily, tabuľka nižšie zhrňuje rozhodovacie kritériá, ktoré ma osobne vedú k voľbe MMKV vo väčšine nových projektov. Údaje sú kalibrované na verzie react-native-mmkv 3.2 a @react-native-async-storage/async-storage 2.5 (obe stav september 2026).
Vlastnosť
MMKV
AsyncStorage
API
Synchrónne cez JSI
Asynchrónne, Promise založené
Rýchlosť zápisu (1 kB)
~0,02 ms
~0,6 ms
Rýchlosť čítania (1 kB)
~0,01 ms
~0,1 ms
Šifrovanie
AES-256 (voliteľné)
Nie (Android používa SharedPreferences bez šifrovania)
Viacero inštancií
Áno, oddelené súbory
Nie, jedno globálne úložisko
Nová architektúra
Plná podpora, bridgeless
Podpora od verzie 2.0, TurboModule
Expo Go
Nefunguje (vyžaduje dev build)
Funguje
Veľkosť inštalácie
~180 kB natívne
~40 kB natívne
Reaktivita v Reacte
useMMKVStorage hook priamo v knižnici
Vyžaduje context alebo externý store
Je MMKV naozaj rýchlejšie než AsyncStorage?
Áno, a nie je to marketing. Dá sa to reprodukovať za pár minút. V mojom poslednom benchmarku som na Pixeli 8 spustil 10 000 zápisov 100-bajtovej hodnoty a MMKV prešlo cez celý cyklus za 187 ms, AsyncStorage za 5 940 ms. To je 31,7-násobok. Rozdiel pochádza z troch vecí: MMKV zapisuje memory-mapped súbory (mmap), volania idú synchrónne cez JSI bez asynchrónneho boundary, a serializuje interne cez protobuf, nie JSON.
Praktické dôsledky v aplikácii sú výraznejšie tam, kde beží veľa malých čítaní pri štarte, napríklad rehydratácia stavu, feature flagov, tokenov, user settings. Ja to typicky vidím v článku o optimalizácii štartu React Native aplikácie: len prechod z AsyncStorage.getItem na MMKV.getString vie ušetriť 150 až 400 ms TTI, pretože prvý render už nečaká na Promise.
// Benchmark, ktorý si môžete spustiť
import AsyncStorage from '@react-native-async-storage/async-storage';
import { MMKV } from 'react-native-mmkv';
const storage = new MMKV();
export async function benchmark() {
const iterations = 10_000;
const payload = 'x'.repeat(100);
// AsyncStorage
const asyncStart = performance.now();
for (let i = 0; i < iterations; i++) {
await AsyncStorage.setItem(`async_${i}`, payload);
}
const asyncTime = performance.now() - asyncStart;
// MMKV
const mmkvStart = performance.now();
for (let i = 0; i < iterations; i++) {
storage.set(`mmkv_${i}`, payload);
}
const mmkvTime = performance.now() - mmkvStart;
console.log(`AsyncStorage: ${asyncTime.toFixed(0)} ms`);
console.log(`MMKV: ${mmkvTime.toFixed(0)} ms`);
console.log(`Speedup: ${(asyncTime / mmkvTime).toFixed(1)}x`);
}
Jedna vec, ktorú je fér zdôrazniť: pri hodnotách nad približne 50 kB rozdiel klesá, pretože obe knižnice trávia väčšinu času vlastným I/O a serializáciou. MMKV má stále mierny náskok, ale očakávaný speedup je 3 až 5× miesto 30×. Preto pre veľké payloady (obrázky, cache API responses) považujem obe za nesprávny nástroj. Použite expo-file-system alebo SQLite.
Inštalácia MMKV v Expo a bare React Native
V bare React Native projekte je inštalácia priamočiara: yarn add react-native-mmkv, na iOS pod install, na Androide žiadny ďalší krok. V Expo je scenár trošku odlišný, lebo react-native-mmkv obsahuje JSI natívny kód, ktorý sa v Expo Go nedá načítať. Musíte prejsť na Expo development build.
# Bare React Native
yarn add react-native-mmkv
cd ios && pod install
# Expo (Managed Workflow s dev build)
npx expo install react-native-mmkv
npx expo prebuild --clean # vygeneruje ios/ a android/ zložky
eas build --profile development --platform ios
Ak plánujete zostať na Expo Go, MMKV nie je pre vás. Dôvod je čisto architektonický: Expo Go je preddefinovaná binárka s pevnou sadou natívnych modulov. To isté sa týka react-native-reanimated, react-native-skia a všetkých JSI knižníc. V Expo SDK 55 sa dev build stal v podstate štandardom a EAS Build ho vyrába za 8 až 12 minút, takže bariéra je dnes minimálna.
Ako používať MMKV: základné operácie a hooky
Základné API je zámerne úzke: set, getString, getNumber, getBoolean, delete, clearAll, getAllKeys. Neexistuje getObject, JSON si serializujete sami. Zvyknem si vytvoriť jednu inštanciu pre app-wide settings a druhú, šifrovanú, pre tokeny.
// storage/index.ts
import { MMKV } from 'react-native-mmkv';
export const settingsStorage = new MMKV({
id: 'user-settings',
});
export const secureStorage = new MMKV({
id: 'auth-tokens',
encryptionKey: process.env.EXPO_PUBLIC_MMKV_KEY, // 32 znakov, uložený mimo repa
});
// Uloženie objektu
type UserPreferences = { theme: 'light' | 'dark'; locale: string };
export function savePreferences(prefs: UserPreferences) {
settingsStorage.set('preferences', JSON.stringify(prefs));
}
export function loadPreferences(): UserPreferences | null {
const raw = settingsStorage.getString('preferences');
return raw ? JSON.parse(raw) : null;
}
Pre reaktivitu v Reacte prichádza knižnica s hookom useMMKVString a jeho variantmi. Komponent sa prerenderuje, keď sa hodnota kľúča zmení, bez toho, aby ste museli zavesiť vlastný listener alebo Zustand store.
MMKV podporuje viac inštancií cez parameter id. V praxi to používam na oddelenie citlivých údajov (šifrovaná inštancia) od bežných preferencií (nešifrovaná, väčšia). Multi-process prístup je na Androide podporovaný natívne cez MMKV_MULTI_PROCESS, čo oceníte pri background services alebo notification handlers.
Je MMKV šifrované a bezpečné pre citlivé dáta?
MMKV podporuje AES-256 v CFB móde, ak inštancii pri konštrukcii dodáte encryptionKey. Kľúč musí mať aspoň 16 bajtov a knižnica sama ho neuchováva, kladiete ho vy. To znamená, že šifrovanie chráni obsah súboru na disku, ale kľúč musíte niekde uložiť, ideálne v expo-secure-store (iOS Keychain, Android EncryptedSharedPreferences). AsyncStorage takúto voľbu nemá. Na Androide sedí v SharedPreferences, ktoré sú v /data/data pre root/adb prístup čitateľné otvorene.
Pre veľmi citlivé dáta ako OAuth refresh tokeny alebo biometrické identifikátory osobne stále preferujem expo-secure-store alebo priamo iOS Keychain, nie preto, že by MMKV šifrovanie bolo slabé, ale preto, že kľúče v Keychain sú viazané na Face ID a biometriu a operačný systém ich pri jailbreaku vie zablokovať. MMKV je super pre stredne citlivé dáta: user profil, feature flagy, cached API tokeny s krátkou životnosťou.
import * as SecureStore from 'expo-secure-store';
import { MMKV } from 'react-native-mmkv';
async function initSecureStorage() {
let key = await SecureStore.getItemAsync('mmkv-key');
if (!key) {
// 32 náhodných bajtov ako hex string
key = Array.from(crypto.getRandomValues(new Uint8Array(32)))
.map((b) => b.toString(16).padStart(2, '0'))
.join('');
await SecureStore.setItemAsync('mmkv-key', key);
}
return new MMKV({ id: 'secure', encryptionKey: key });
}
Ako migrovať z AsyncStorage do MMKV
Migračná stratégia, ktorú používam v produkcii, sa opiera o dve pravidlá: (1) migrácia beží raz, pri prvom otvorení novej verzie, a jej výsledok označíme flagom v samotnom MMKV; (2) staré AsyncStorage kľúče nezmazávam okamžite, ale až po dvoch minor verziách, kým máme istotu, že sa nikto nevracia na predchádzajúcu binárku cez OTA rollback. Pre OTA aktualizácie odporúčam pozrieť aj sprievodcu EAS Update 2026, kde je bezpečná rollback stratégia popísaná podrobne.
import AsyncStorage from '@react-native-async-storage/async-storage';
import { MMKV } from 'react-native-mmkv';
const storage = new MMKV();
const MIGRATION_FLAG = 'mmkv_migrated_v1';
export async function migrateFromAsyncStorage() {
if (storage.getBoolean(MIGRATION_FLAG)) return;
try {
const keys = await AsyncStorage.getAllKeys();
const entries = await AsyncStorage.multiGet(keys);
for (const [key, value] of entries) {
if (value !== null) storage.set(key, value);
}
storage.set(MIGRATION_FLAG, true);
console.log(`Migrácia hotová: prenesených ${entries.length} kľúčov`);
} catch (err) {
// Neblokujte štart appky, len logujte
console.warn('MMKV migrácia zlyhala', err);
}
}
Zavolajte migrateFromAsyncStorage() raz v App.tsx pred rehydratáciou stavu. V Reacte 19 sa to hodí dať do useEffect s prázdnou dependency array, alebo použite SplashScreen.preventAutoHideAsync() a manuálne skryte splash po dokončení migrácie. Priemerný čas na 200 kľúčov je pod 40 ms, používateľ nič neuvidí.
Čo s Redux Persist a Zustand persist middleware?
Oba adaptéry akceptujú vlastné storage backendy. Pri Zustande je to jeden čitateľný jedno-liner. Celá otázka správy stavu v React Native sa tým výrazne uľahčí, pretože rehydratácia po štarte je synchrónna a nemusíte riešiť fázu, keď je store prázdny.
MMKV so Zustandom, Redux Persist a TanStack Query
Pre Zustand ide o priamu implementáciu PersistStorage rozhrania. Pretože MMKV nevracia Promise, výsledok je čistý synchrónny wrapper:
Pre TanStack Query použite @tanstack/query-async-storage-persister so synchrónnym adaptérom. Knižnica síce očakáva async API, ale MMKV wrapper vracia okamžite resolved Promise a nič sa nerozbije. Podľa oficiálnej dokumentácie TanStack Query je toto podporovaný pattern.
Kedy zostať pri AsyncStorage a nemigrovať
Priznávam, že MMKV nie je automatická voľba. Zostal by som pri AsyncStorage v troch scenároch: (1) aplikácia beží čisto v Expo Go a nechcete alebo nemôžete prejsť na dev build, (2) máte staršiu app na React Native pod 0.71 bez plánu na upgrade a JSI natívne moduly by boli riziko, (3) váš use case je jednoduchý, pár kľúčov, žiadny critical path pri štarte, a nechcete zaťažiť tím ďalšou závislosťou.
Druhá vec, ktorú vidím v produkcii: ak vaša app už používa expo-sqlite alebo op-sqlite na relačné dáta, prídavné key-value úložisko nemá zmysel. SQLite s WAL módom je len o percentá pomalší než MMKV pri single-key operáciách a získate transakcie, indexy, dotazy. Pre komplexnejšie scenáre (offline sync, timeline, chat história) je SQLite alebo WatermelonDB stále lepšia voľba ako MMKV.
Zhrnuté z pohľadu 2026: pre každú novú React Native aplikáciu, ktorú zakladám, ide MMKV pre small-to-medium state (do ~5 MB celkom), expo-secure-store pre autentifikačné tokeny a expo-sqlite pre všetko, čo vyžaduje dotazy. AsyncStorage nechávam len tam, kde legacy kód nechce nikto meniť.
Často kladené otázky
Funguje MMKV s Novou architektúrou a bridgeless režimom?
Áno. Od verzie 3.0 (apríl 2026) má react-native-mmkv plnú podporu Fabric, TurboModules aj bridgeless režimu, ktorý je od React Native 0.79 predvolený. Nepotrebujete žiadne kompatibilné flagy ani interop layer.
Môžem MMKV použiť v Expo Go?
Nie. MMKV vyžaduje JSI natívny kód, ktorý Expo Go nenačíta. Potrebujete Expo development build cez eas build --profile development alebo lokálne cez npx expo run:ios / run:android.
Aký veľký objem dát znesie MMKV?
Odporúčaný limit je približne 5 až 10 MB na inštanciu. Nad túto hranicu začne trpieť čas prvého new MMKV(), pretože mmap si celý súbor zavedie do pamäte. Pre väčšie dáta prejdite na SQLite alebo WatermelonDB.
Dá sa MMKV použiť z Web (React Native for Web)?
Priamo nie, MMKV je natívna knižnica. Pre React Native Web použite fallback na localStorage alebo IndexedDB pomocou platform-check patternu (Platform.OS === 'web').
Musím po migrácii z AsyncStorage vymazať staré dáta?
Nie okamžite. Odporúčam nechať AsyncStorage kľúče ešte 2 minor verzie kvôli možnému OTA rollbacku cez EAS Update. Po overení, že žiadny používateľ sa nevracia na starú binárku, zavolajte AsyncStorage.clear() v ďalšom release.
Nitro Modules v React Native 2026 nahrádzajú TurboModules synchrónnym JSI mostom cez HybridObject. Pozrite si porovnanie s Expo Modules API, ukážky v Swifte a Kotline aj to, ktoré knižnice (MMKV 3, VisionCamera 5) už na Nitro bežia.
Praktický sprievodca push notifikáciami v Expo pre rok 2026: konfigurácia FCM v1 a APNs, získanie ExponentPushTokenu, odosielanie zo servera, notifikačné kanály na Androide a spracovanie interakcií vrátane cold-startu.
CodePush skončil v marci 2025 a EAS Update je jeho oficiálny nástupca. Ukážeme si nastavenie kanálov, fingerprint runtime versioning, postupné rollouty od 5 %, tri spôsoby rollbacku a bundle diffing zavedený v Expo SDK 55.