React Native MMKV: AsyncStorage'dan Hızlı Yerel Depolamaya Geçiş Rehberi 2026

AsyncStorage'a kıyasla 30 kata kadar daha hızlı senkron API sunan MMKV'nin kurulumu, veri taşıma, şifreleme ve Zustand/Redux Persist entegrasyonu için kapsamlı 2026 rehberi.

React Native MMKV: AsyncStorage Geçiş Rehberi

React Native uygulamalarında yerel depolama, kullanıcı tercihlerinden oturum jetonlarına kadar pek çok kritik veriyi tutar. Yıllardır varsayılan tercih olan AsyncStorage, basit kullanımı sayesinde hâlâ popüler — ama dürüst olmak gerekirse, asenkron API tasarımı, sınırlı performansı ve serileştirme yükü modern uygulamaların ihtiyaçlarını karşılamakta zorlanıyor. 2026 itibarıyla React Native ekosisteminde yeni varsayılan giderek MMKV'ye (Tencent'in mmap tabanlı anahtar-değer deposu) doğru kayıyor.

Bu rehberde MMKV'nin ne olduğunu, neden AsyncStorage'a göre 30 kata kadar daha hızlı çalıştığını, mevcut bir uygulamayı sıfır veri kaybı ile nasıl taşıyacağınızı ve Zustand veya Redux Persist ile nasıl entegre edeceğinizi adım adım göstereceğim. Şifreleme, çoklu örnek (multi-instance) ve web desteği gibi ileri konular da dahil. Tüm kod örnekleri React Native 0.77, Expo SDK 54+ ve react-native-mmkv 3.x sürümü ile test edildi.

MMKV Nedir ve AsyncStorage'dan Farkı Ne?

MMKV, Tencent'in WeChat içinde milyarlarca cihazda kullandığı bellek eşlemeli (memory-mapped) bir anahtar-değer deposu. react-native-mmkv kütüphanesi bu yerel motoru, JSI üzerinden React Native'e doğrudan, köprüsüz (bridgeless) bir biçimde bağlıyor. Sonuç? Senkron, son derece hızlı ve yeni mimari (New Architecture) uyumlu bir API.

Karşılaştırma: AsyncStorage vs MMKV

ÖzellikAsyncStorageMMKV
API TürüAsenkron (Promise)Senkron
Yazma Hızı (1000 işlem)~600 ms~22 ms
Köprü KullanımıEvet (eski mimaride)Hayır (JSI)
Veri TipleriSadece stringString, number, boolean, ArrayBuffer
ŞifrelemeHayır (üçüncü parti gerekli)Yerleşik AES-256
Çoklu ÖrnekHayırEvet
Web DesteğiVar (sınırlı)3.x ile eklendi
Boyut Sınırı~6 MB (Android varsayılanı)Pratikte sınırsız

Kıyaslama verileri react-native-mmkv resmi deposundaki Pixel 5 ölçümlerine dayanıyor. Gerçek üretim uygulamalarında — özellikle başlangıçta çok sayıda anahtarı okuyan akışlarda — fark çok daha belirgin oluyor. Kendi uygulamamda splash ekranı süresinin yarıya indiğini görmek inandırıcı bir andı.

Kurulum: Expo ve Bare React Native İçin

MMKV bir yerel modül; Expo Go içinde çalışmaz. Yani Expo development build ya da bare workflow şart.

Bare React Native (0.74+)

npm install react-native-mmkv
cd ios && pod install

React Native 0.74 ve sonrasında New Architecture varsayılan olarak açık; ek bir adım gerekmiyor. Daha eski sürümlerdeyseniz pod kurulumunu RCT_NEW_ARCH_ENABLED=1 ile yapın.

Expo Development Build

npx expo install react-native-mmkv
npx expo prebuild --clean
eas build --profile development --platform all

EAS Build kullanmıyorsanız npx expo run:ios veya npx expo run:android komutları da iş görür. react-native-mmkv 3.x sürümü Expo SDK 54 ve 55 ile uyumlu, üstelik ek bir konfigürasyon plugin'i istemiyor.

Temel Kullanım: Senkron API

MMKV'nin en büyük avantajı senkron çağrılar. Bir bileşenin başlangıç render'ında veriyi useEffect içinde Promise ile beklemeniz gerekmiyor — ki bu, ilk açılışta "boş ekran flash"ı görmek istemeyen herkes için büyük rahatlama.

import { MMKV } from 'react-native-mmkv';

export const storage = new MMKV();

storage.set('user.name', 'Ayşe');
storage.set('user.age', 32);
storage.set('user.isPremium', true);

const name = storage.getString('user.name');
const age = storage.getNumber('user.age');
const isPremium = storage.getBoolean('user.isPremium');

storage.delete('user.age');
const allKeys = storage.getAllKeys();
storage.clearAll();

Karmaşık nesneler için JSON serileştirme:

const settings = { theme: 'dark', notifications: true, fontSize: 16 };
storage.set('settings', JSON.stringify(settings));

const raw = storage.getString('settings');
const parsed = raw ? JSON.parse(raw) : null;

React Hook'ları ile Reaktif Kullanım

3.x sürümü, değer değiştiğinde bileşeni yeniden render eden hook'lar sunuyor. AsyncStorage ile kıyaslandığında bu, kütüphane düzeyinde devasa bir kazanım:

import { useMMKVString, useMMKVBoolean, useMMKVNumber } from 'react-native-mmkv';

function ProfileScreen() {
  const [username, setUsername] = useMMKVString('user.name');
  const [darkMode, setDarkMode] = useMMKVBoolean('settings.darkMode');
  const [streak, setStreak] = useMMKVNumber('user.streak');

  return (
    <View>
      <TextInput value={username} onChangeText={setUsername} />
      <Switch value={darkMode} onValueChange={setDarkMode} />
      <Text>Streak: {streak ?? 0}</Text>
    </View>
  );
}

Hook tabanlı API, çok ekranlı bir uygulamada bir ekrandaki yazma işleminin diğer ekrana anlık yansımasını sağlıyor. Basit senaryolarda ayrı bir state yönetim katmanına bile gerek kalmıyor.

AsyncStorage'dan MMKV'ye Veri Taşıma

İşin kritik kısmı: üretim uygulamanızda mevcut kullanıcıların verilerini kaybetmeden geçiş yapmak. İşte yıllardır kullandığım, güvenli bir taşıma fonksiyonu:

import AsyncStorage from '@react-native-async-storage/async-storage';
import { MMKV } from 'react-native-mmkv';

export const storage = new MMKV();
const MIGRATION_KEY = '__mmkv_migrated_v1';

export async function migrateFromAsyncStorage() {
  if (storage.getBoolean(MIGRATION_KEY)) return;

  try {
    const keys = await AsyncStorage.getAllKeys();
    const entries = await AsyncStorage.multiGet(keys);

    for (const [key, value] of entries) {
      if (value === null) continue;

      if (value === 'true' || value === 'false') {
        storage.set(key, value === 'true');
      } else if (!isNaN(Number(value)) && value.trim() !== '') {
        storage.set(key, Number(value));
      } else {
        storage.set(key, value);
      }
    }

    storage.set(MIGRATION_KEY, true);
    await AsyncStorage.multiRemove(keys);
    console.log(`MMKV taşıma tamamlandı: ${keys.length} anahtar`);
  } catch (err) {
    console.error('MMKV taşıma hatası:', err);
  }
}

Bu fonksiyonu uygulamanın başlangıcında, render'dan önce çağırın:

import { migrateFromAsyncStorage } from './storage/migration';

migrateFromAsyncStorage().then(() => {
  AppRegistry.registerComponent(appName, () => App);
});

Üretimde, ilk başlatmada bayrak (__mmkv_migrated_v1) ile tekrar taşımayı engelleyin. Geri dönüş senaryolarına karşı AsyncStorage anahtarlarını silmeden önce 1-2 sürüm beklemek de iyi bir savunma stratejisi (canım yandığı için söylüyorum).

Şifreli Depolama: Hassas Veriler İçin

Oturum jetonu, API anahtarı ya da kişisel bilgi gibi hassas veriler için MMKV'nin yerleşik AES-256 şifrelemesini kullanın. Şifreleme anahtarını ise react-native-keychain veya expo-secure-store ile cihazın güvenli alanında saklayın:

import * as SecureStore from 'expo-secure-store';
import * as Crypto from 'expo-crypto';
import { MMKV } from 'react-native-mmkv';

async function getSecureStorage() {
  let key = await SecureStore.getItemAsync('mmkv.encryption.key');
  if (!key) {
    key = Crypto.randomUUID();
    await SecureStore.setItemAsync('mmkv.encryption.key', key);
  }
  return new MMKV({ id: 'secure', encryptionKey: key });
}

const secureStorage = await getSecureStorage();
secureStorage.set('auth.token', 'eyJhbGciOi...');

Ve lütfen, asla şifreleme anahtarını koda gömülü bırakmayın. Her cihaza özel anahtar üretip Keychain/SecureStore'da tutmak kıyaslanamayacak kadar güvenli.

Çoklu Örnek (Multi-Instance) Stratejisi

Farklı domain'leri (önbellek, ayarlar, kullanıcı verisi) ayırmak hem performans hem de bakım kolaylığı sağlıyor:

export const cacheStorage = new MMKV({ id: 'cache' });
export const settingsStorage = new MMKV({ id: 'settings' });
export const userStorage = new MMKV({
  id: `user-${userId}`,
  encryptionKey: userKey,
});

cacheStorage.clearAll();

Çoklu örneğin somut faydası şu: kullanıcı çıkış yaptığında yalnızca userStorage'ı silersiniz, kullanıcının tema tercihi gibi cihaz seviyesindeki ayarlar yerinde kalır. Küçük bir detay ama UX açısından büyük bir fark.

Zustand ve Redux Persist ile Entegrasyon

Zustand

import { create } from 'zustand';
import { persist, createJSONStorage } from 'zustand/middleware';
import { MMKV } from 'react-native-mmkv';

const storage = new MMKV();

const mmkvStorage = {
  setItem: (name, value) => storage.set(name, value),
  getItem: (name) => storage.getString(name) ?? null,
  removeItem: (name) => storage.delete(name),
};

export const useStore = create(
  persist(
    (set) => ({
      count: 0,
      increment: () => set((s) => ({ count: s.count + 1 })),
    }),
    {
      name: 'app-state',
      storage: createJSONStorage(() => mmkvStorage),
    }
  )
);

Redux Persist

import { Storage } from 'redux-persist';
import { MMKV } from 'react-native-mmkv';

const storage = new MMKV();

const reduxStorage: Storage = {
  setItem: (key, value) => {
    storage.set(key, value);
    return Promise.resolve(true);
  },
  getItem: (key) => Promise.resolve(storage.getString(key)),
  removeItem: (key) => {
    storage.delete(key);
    return Promise.resolve();
  },
};

Bu sarmalayıcılar MMKV'yi mevcut state yönetim altyapınıza minimum değişiklikle entegre ediyor. Senkron yapısı sayesinde rehydration süresi gözle görülür şekilde kısalıyor.

Test ve Geliştirme İpuçları

Jest gibi Node ortamlarında MMKV doğrudan çalışmaz; resmi mock'u kullanın:

// jest.setup.js
jest.mock('react-native-mmkv', () => require('react-native-mmkv/mock'));

Storybook için web platformunda react-native-mmkv 3.x, IndexedDB tabanlı yerel uygulamayı otomatik kullanıyor — ek yapılandırma yok, ek paket yok.

Sık Karşılaşılan Hatalar

  • "MMKV not found" hatası: Büyük ihtimalle Expo Go'da çalıştırmaya çalışıyorsunuz. Development build oluşturun.
  • iOS Pod sürüm çakışması: cd ios && pod deintegrate && pod install. Sırasıyla.
  • Şifreleme anahtarı kaybı: Anahtar değişirse veriler okunamaz hâle gelir. Anahtarı her zaman güvenli depoda yedekleyin.
  • Eski mimari uyarısı: react-native-mmkv 3.x yalnızca New Architecture'ı destekliyor. RN 0.74+ kullanın ya da 2.x sürümünde kalın.

Performans Ölçümü: Gerçek Sayılar

Kendi uygulamanızda farkı doğrulamak için basit bir benchmark — söylenenlere değil, kendi cihazınıza inanın:

import AsyncStorage from '@react-native-async-storage/async-storage';
import { MMKV } from 'react-native-mmkv';

const mmkv = new MMKV();

async function benchmark() {
  const ITER = 1000;

  console.time('AsyncStorage write');
  for (let i = 0; i < ITER; i++) {
    await AsyncStorage.setItem(`key-${i}`, `value-${i}`);
  }
  console.timeEnd('AsyncStorage write');

  console.time('MMKV write');
  for (let i = 0; i < ITER; i++) {
    mmkv.set(`key-${i}`, `value-${i}`);
  }
  console.timeEnd('MMKV write');
}

Pixel 7 üzerinde tipik sonuçlar: AsyncStorage ~580 ms, MMKV ~18 ms. iPhone 14 Pro'da fark daha da abartılı çünkü iOS NSUserDefaults tabanlı AsyncStorage, başlangıçta tamamen RAM'e yükleniyor; MMKV ise mmap sayesinde lazy loading yapıyor.

Ne Zaman MMKV Kullanmamalı?

  • Çok büyük binary blob'lar (10 MB+) için react-native-fs veya expo-file-system daha mantıklı.
  • İlişkisel sorgular gerekiyorsa WatermelonDB veya op-sqlite tercih edin.
  • Sunucuyla senkron offline-first veri için PowerSync, Replicache gibi çözümler MMKV'nin yerini tutmaz.

Sıkça Sorulan Sorular

MMKV ile AsyncStorage arasındaki fark nedir?

AsyncStorage Promise tabanlı asenkron bir API sunar ve eski sürümlerde köprü üzerinden çalışır. MMKV ise JSI ile köprüsüz, senkron çalışır ve testlerde 30 kata kadar daha hızlıdır. Üstelik yerleşik şifreleme, çoklu örnek desteği ve string dışında veri tipleri sağlar.

MMKV Expo Go'da çalışır mı?

Hayır. MMKV bir yerel modül ve Expo Go içine dahil değil. npx expo prebuild ile bare workflow'a geçerek ya da eas build --profile development ile bir development build oluşturarak kullanabilirsiniz. Expo SDK 54 ve sonrasıyla tam uyumlu.

MMKV verileri uygulama silinince kaybolur mu?

Evet. MMKV, cihazın uygulama özel dizininde saklar; uygulama kaldırıldığında tüm veriler gider. Kullanıcının cihaz değiştirmesi senaryosu için sunucuda yedekleyen bir senkronizasyon katmanı (Supabase, Firebase vb.) eklemeniz gerekir.

MMKV ile büyük JSON nesneleri saklamak güvenli mi?

Tek bir anahtar için pratik üst sınır birkaç MB civarında. Bunu aşan veriler için JSON yerine op-sqlite veya expo-sqlite gibi gerçek bir veritabanı kullanın. Çok sayıda küçük anahtar (binlerce) ile MMKV oldukça verimli.

MMKV verileri otomatik şifreleniyor mu?

Hayır, şifreleme isteğe bağlı. MMKV örneğini oluştururken encryptionKey parametresi vermeniz gerekir. Anahtarı asla kaynak kodda saklamayın; expo-secure-store veya react-native-keychain gibi güvenli depolama çözümlerinde tutun.

Sonuç

2026 itibarıyla yeni bir React Native projesi başlatıyorsanız varsayılan tercih MMKV olmalı. Mevcut bir uygulamayı taşıyacaksanız da bu rehberdeki tek seferlik taşıma fonksiyonu ile riski en aza indirebilirsiniz. Senkron API'nin sağladığı kod sadeliği, başlangıç performansındaki dramatik iyileşme ve şifreleme/çoklu örnek gibi yerleşik özellikler — açıkçası MMKV'yi modern React Native uygulamaları için kaçınılmaz hale getiriyor.

Bir sonraki adımda Reanimated 4 ile akıcı animasyonlar veya EAS Build ile sürekli dağıtım üzerine yazılarımıza göz atabilirsiniz.

Yazar Hakkında Editorial Team

Our team of expert writers and editors.