Convert Figma logo to code with AI

mrousavy logoreact-native-mmkv

⚡️ The fastest key/value storage for React Native. ~30x faster than AsyncStorage!

7,316
285
7,316
55

Top Related Projects

Realm is a mobile database: an alternative to SQLite & key-value stores

An ultra fast (0.0002s read/write), small & encrypted mobile key-value storage framework for React Native written in C++ using JSI

An asynchronous, persistent, key-value storage system for React Native.

🍉 Reactive & asynchronous database for powerful React and React Native apps ⚡️

:key: Keychain Access for React Native

Quick Overview

React Native MMKV is a high-performance, efficient key-value storage library for React Native applications. It's built on top of MMKV, a key-value storage framework developed by WeChat, offering superior speed and efficiency compared to AsyncStorage.

Pros

  • Extremely fast read/write operations, significantly outperforming AsyncStorage
  • Supports various data types including strings, numbers, booleans, and objects
  • Encryption support for enhanced data security
  • Lightweight and easy to integrate into existing React Native projects

Cons

  • Limited to key-value storage, not suitable for complex data structures
  • Requires additional setup for iOS projects (CocoaPods)
  • May have a steeper learning curve compared to AsyncStorage for beginners
  • Limited cross-platform compatibility (only iOS and Android)

Code Examples

  1. Basic usage:
import { MMKV } from 'react-native-mmkv'

const storage = new MMKV()

// Set a value
storage.set('user', 'John Doe')

// Get a value
const user = storage.getString('user')
console.log(user) // 'John Doe'
  1. Working with different data types:
// Store a number
storage.set('age', 30)

// Store a boolean
storage.set('isLoggedIn', true)

// Store an object
storage.set('userDetails', JSON.stringify({ name: 'John', age: 30 }))

// Retrieve values
const age = storage.getNumber('age')
const isLoggedIn = storage.getBoolean('isLoggedIn')
const userDetails = JSON.parse(storage.getString('userDetails'))
  1. Using encryption:
import { MMKV } from 'react-native-mmkv'

const storage = new MMKV({
  id: 'user-storage',
  encryptionKey: 'my-secret-key'
})

storage.set('password', 'securePassword123')
const password = storage.getString('password')

Getting Started

  1. Install the package:

    npm install react-native-mmkv
    
  2. For iOS, install pods:

    cd ios && pod install
    
  3. Import and use in your React Native app:

    import { MMKV } from 'react-native-mmkv'
    
    const storage = new MMKV()
    storage.set('key', 'value')
    const value = storage.getString('key')
    

Competitor Comparisons

Realm is a mobile database: an alternative to SQLite & key-value stores

Pros of Realm

  • Full-featured database solution with advanced querying capabilities
  • Supports real-time synchronization and offline-first architecture
  • Cross-platform compatibility (iOS, Android, and web)

Cons of Realm

  • Steeper learning curve due to more complex API
  • Larger bundle size and potential performance overhead for simpler use cases
  • Requires more setup and configuration

Code Comparison

React Native MMKV:

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

const storage = new MMKV();
storage.set('user', JSON.stringify({ name: 'John', age: 30 }));
const user = JSON.parse(storage.getString('user'));

Realm:

import Realm from 'realm';

const UserSchema = {
  name: 'User',
  properties: { name: 'string', age: 'int' }
};

const realm = await Realm.open({ schema: [UserSchema] });
realm.write(() => {
  realm.create('User', { name: 'John', age: 30 });
});
const user = realm.objects('User')[0];

React Native MMKV is a lightweight key-value storage solution, while Realm is a full-featured mobile database. MMKV offers simplicity and high performance for basic storage needs, whereas Realm provides more advanced features like real-time synchronization and complex querying at the cost of increased complexity and setup.

An ultra fast (0.0002s read/write), small & encrypted mobile key-value storage framework for React Native written in C++ using JSI

Pros of react-native-mmkv-storage

  • Provides a higher-level API with more convenience methods
  • Includes built-in encryption support
  • Offers additional utility functions like clearStore() and clearMemoryCache()

Cons of react-native-mmkv-storage

  • Less actively maintained (last update over a year ago)
  • Larger package size due to additional features
  • Potentially slower performance due to the abstraction layer

Code Comparison

react-native-mmkv:

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

const storage = new MMKV();
storage.set('user', JSON.stringify({ name: 'John', age: 30 }));
const user = JSON.parse(storage.getString('user'));

react-native-mmkv-storage:

import MMKVStorage from 'react-native-mmkv-storage';

const MMKV = new MMKVStorage.Loader().initialize();
await MMKV.setMapAsync('user', { name: 'John', age: 30 });
const user = await MMKV.getMapAsync('user');

The react-native-mmkv library provides a more low-level API, requiring manual JSON parsing and stringification. In contrast, react-native-mmkv-storage offers convenience methods for handling complex data types, such as setMapAsync and getMapAsync.

While react-native-mmkv-storage provides more features out of the box, react-native-mmkv offers a simpler, more performant solution for basic key-value storage needs. The choice between the two depends on the specific requirements of your project and the level of abstraction you prefer.

An asynchronous, persistent, key-value storage system for React Native.

Pros of async-storage

  • Widely adopted and well-established in the React Native ecosystem
  • Simple API that closely resembles the Web Storage API
  • Supports both synchronous and asynchronous operations

Cons of async-storage

  • Slower performance compared to MMKV, especially for large datasets
  • Limited data type support (mainly strings)
  • Lacks built-in encryption for sensitive data

Code Comparison

async-storage:

import AsyncStorage from '@react-native-async-storage/async-storage';

await AsyncStorage.setItem('key', 'value');
const value = await AsyncStorage.getItem('key');

MMKV:

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

const storage = new MMKV();
storage.set('key', 'value');
const value = storage.getString('key');

MMKV offers a more performant solution with support for various data types and encryption. It uses a synchronous API, which can be beneficial for certain use cases. However, async-storage remains a popular choice due to its simplicity and familiarity, especially for developers transitioning from web development. The choice between the two depends on specific project requirements, performance needs, and developer preferences.

🍉 Reactive & asynchronous database for powerful React and React Native apps ⚡️

Pros of WatermelonDB

  • Supports complex relational data structures and queries
  • Offers robust synchronization capabilities for offline-first apps
  • Provides a more comprehensive database solution with advanced features

Cons of WatermelonDB

  • Higher learning curve and more complex setup compared to MMKV
  • Potentially slower performance for simple key-value storage operations
  • Larger bundle size and increased app complexity

Code Comparison

WatermelonDB:

import { Database } from '@nozbe/watermelondb'
import { mySchema } from './model/schema'

const database = new Database({
  adapter: new SQLiteAdapter({ schema: mySchema }),
  modelClasses: [/* ... */],
})

MMKV:

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

const storage = new MMKV()
storage.set('user', JSON.stringify({ name: 'Marc' }))
const user = JSON.parse(storage.getString('user'))

WatermelonDB is better suited for complex data structures and relationships, offering advanced querying and synchronization features. However, it comes with a steeper learning curve and potentially slower performance for simple storage tasks. MMKV, on the other hand, provides a simpler and faster solution for basic key-value storage needs but lacks the advanced database features of WatermelonDB.

:key: Keychain Access for React Native

Pros of react-native-keychain

  • Specialized for secure storage of sensitive data like passwords and tokens
  • Utilizes platform-specific secure storage mechanisms (Keychain on iOS, Keystore on Android)
  • Supports biometric authentication for added security

Cons of react-native-keychain

  • Limited to storing key-value pairs, not suitable for large datasets
  • Slower read/write operations compared to MMKV
  • More complex setup and usage for basic data storage needs

Code Comparison

react-native-keychain:

import * as Keychain from 'react-native-keychain';

await Keychain.setGenericPassword('username', 'password');
const credentials = await Keychain.getGenericPassword();

react-native-mmkv:

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

const storage = new MMKV();
storage.set('user', 'username');
const user = storage.getString('user');

react-native-keychain is ideal for storing sensitive information securely, leveraging platform-specific security features. It's more suitable for credentials and tokens but has limitations in terms of storage capacity and speed.

react-native-mmkv, on the other hand, offers faster read/write operations and can handle larger datasets. It's more versatile for general data storage but may not be as secure for sensitive information.

Choose based on your specific needs: security (keychain) vs. performance and flexibility (MMKV).

Convert Figma logo designs to code with AI

Visual Copilot

Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.

Try Visual Copilot

README

react-native-mmkv

MMKV

The fastest key/value storage for React Native.


  • MMKV is an efficient, small mobile key-value storage framework developed by WeChat. See Tencent/MMKV for more information
  • react-native-mmkv is a library that allows you to easily use MMKV inside your React Native app through fast and direct JS bindings to the native C++ library.

Features

  • Get and set strings, booleans, numbers and ArrayBuffers
  • Fully synchronous calls, no async/await, no Promises, no Bridge.
  • Encryption support (secure storage)
  • Multiple instances support (separate user-data with global data)
  • Customizable storage location
  • High performance because everything is written in C++
  • ~30x faster than AsyncStorage
  • Uses JSI and C++ TurboModules instead of the "old" Bridge
  • iOS, Android and Web support
  • Easy to use React Hooks API

react-native-mmkv V3

[!IMPORTANT] react-native-mmkv V3 is now a pure C++ TurboModule, and requires the new architecture to be enabled. (react-native 0.75+)

  • If you want to use react-native-mmkv 3.x.x, you need to enable the new architecture in your app (see "Enable the New Architecture for Apps")
  • For React-Native 0.74.x, use react-native-mmkv 3.0.1. For React-Native 0.75.x and higher, use react-native-mmkv 3.0.2 or higher.
  • If you cannot use the new architecture yet, downgrade to react-native-mmkv 2.x.x for now.

Benchmark

StorageBenchmark compares popular storage libraries against each other by reading a value from storage for 1000 times:

MMKV vs other storage libraries: Reading a value from Storage 1000 times.
Measured in milliseconds on an iPhone 11 Pro, lower is better.

Installation

React Native

yarn add react-native-mmkv
cd ios && pod install

Expo

npx expo install react-native-mmkv
npx expo prebuild

Usage

Create a new instance

To create a new instance of the MMKV storage, use the MMKV constructor. It is recommended that you re-use this instance throughout your entire app instead of creating a new instance each time, so export the storage object.

Default

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

export const storage = new MMKV()

This creates a new storage instance using the default MMKV storage ID (mmkv.default).

App Groups or Extensions

If you want to share MMKV data between your app and other apps or app extensions in the same group, open Info.plist and create an AppGroup key with your app group's value. MMKV will then automatically store data inside the app group which can be read and written to from other apps or app extensions in the same group by making use of MMKV's multi processing mode. See Configuring App Groups.

Customize

import { MMKV, Mode } from 'react-native-mmkv'

export const storage = new MMKV({
  id: `user-${userId}-storage`,
  path: `${USER_DIRECTORY}/storage`,
  encryptionKey: 'hunter2',
  mode: Mode.MULTI_PROCESS,
  readOnly: false
})

This creates a new storage instance using a custom MMKV storage ID. By using a custom storage ID, your storage is separated from the default MMKV storage of your app.

The following values can be configured:

  • id: The MMKV instance's ID. If you want to use multiple instances, use different IDs. For example, you can separate the global app's storage and a logged-in user's storage. (required if path or encryptionKey fields are specified, otherwise defaults to: 'mmkv.default')
  • path: The MMKV instance's root path. By default, MMKV stores file inside $(Documents)/mmkv/. You can customize MMKV's root directory on MMKV initialization (documentation: iOS / Android)
  • encryptionKey: The MMKV instance's encryption/decryption key. By default, MMKV stores all key-values in plain text on file, relying on iOS's/Android's sandbox to make sure the file is encrypted. Should you worry about information leaking, you can choose to encrypt MMKV. (documentation: iOS / Android)
  • mode: The MMKV's process behaviour - when set to MULTI_PROCESS, the MMKV instance will assume data can be changed from the outside (e.g. App Clips, Extensions or App Groups).
  • readOnly: Whether this MMKV instance should be in read-only mode. This is typically more efficient and avoids unwanted writes to the data if not needed. Any call to set(..) will throw.

Set

storage.set('user.name', 'Marc')
storage.set('user.age', 21)
storage.set('is-mmkv-fast-asf', true)

Get

const username = storage.getString('user.name') // 'Marc'
const age = storage.getNumber('user.age') // 21
const isMmkvFastAsf = storage.getBoolean('is-mmkv-fast-asf') // true

Hooks

const [username, setUsername] = useMMKVString('user.name')
const [age, setAge] = useMMKVNumber('user.age')
const [isMmkvFastAsf, setIsMmkvFastAf] = useMMKVBoolean('is-mmkv-fast-asf')

Keys

// checking if a specific key exists
const hasUsername = storage.contains('user.name')

// getting all keys
const keys = storage.getAllKeys() // ['user.name', 'user.age', 'is-mmkv-fast-asf']

// delete a specific key + value
storage.delete('user.name')

// delete all keys
storage.clearAll()

Objects

const user = {
  username: 'Marc',
  age: 21
}

// Serialize the object into a JSON string
storage.set('user', JSON.stringify(user))

// Deserialize the JSON string into an object
const jsonUser = storage.getString('user') // { 'username': 'Marc', 'age': 21 }
const userObject = JSON.parse(jsonUser)

Encryption

// encrypt all data with a private key
storage.recrypt('hunter2')

// remove encryption
storage.recrypt(undefined)

Buffers

const buffer = new ArrayBuffer(3)
const dataWriter = new Uint8Array(buffer)
dataWriter[0] = 1
dataWriter[1] = 100
dataWriter[2] = 255
storage.set('someToken', buffer)

const buffer = storage.getBuffer('someToken')
console.log(buffer) // [1, 100, 255]

Size

// get size of MMKV storage in bytes
const size = storage.size
if (size >= 4096) {
  // clean unused keys and clear memory cache
  storage.trim()
}

Testing with Jest or Vitest

A mocked MMKV instance is automatically used when testing with Jest or Vitest, so you will be able to use new MMKV() as per normal in your tests. Refer to package/example/test/MMKV.test.ts for an example using Jest.

Documentation

LocalStorage and In-Memory Storage (Web)

If a user chooses to disable LocalStorage in their browser, the library will automatically provide a limited in-memory storage as an alternative. However, this in-memory storage won't persist data, and users may experience data loss if they refresh the page or close their browser. To optimize user experience, consider implementing a suitable solution within your app to address this scenario.

Limitations

  • react-native-mmkv V3 requires react-native 0.74 or higher.
  • react-native-mmkv V3 requires the new architecture/TurboModules to be enabled.
  • Since react-native-mmkv uses JSI for synchronous native method invocations, remote debugging (e.g. with Chrome) is no longer possible. Instead, you should use Flipper or React DevTools.

Integrations

Flipper

Use flipper-plugin-react-native-mmkv to debug your MMKV storage using Flipper. You can also simply console.log an MMKV instance.

Reactotron

Use reactotron-react-native-mmkv to automatically log writes to your MMKV storage using Reactotron. See the docs for how to setup this plugin with Reactotron.

Community Discord

Join the Margelo Community Discord to chat about react-native-mmkv or other Margelo libraries.

Adopting at scale

react-native-mmkv is provided as is, I work on it in my free time.

If you're integrating react-native-mmkv in a production app, consider funding this project and contact me to receive premium enterprise support, help with issues, prioritize bugfixes, request features, help at integrating react-native-mmkv, and more.

Contributing

See the contributing guide to learn how to contribute to the repository and the development workflow.

License

MIT

NPM DownloadsLast 30 Days