Files
2026-06-03 09:55:32 +08:00
..
2026-06-03 09:55:32 +08:00
2026-06-03 09:55:32 +08:00
2026-06-03 09:55:32 +08:00
2026-06-03 09:55:32 +08:00
2026-06-03 09:55:32 +08:00
2026-06-03 09:55:32 +08:00
2026-06-03 09:55:32 +08:00

MMKV for Kotlin Multiplatform

MMKV is an efficient, small, easy-to-use key-value storage framework used in the WeChat application. The Kotlin Multiplatform wrapper exposes one common Kotlin API in com.tencent.mmkv.kmp for Android, iOS, macOS, Linux, Windows, and JVM desktop.

Features

  • Efficient. MMKV uses mmap to keep memory synced with files and protobuf to encode/decode values.

    • Multi-process concurrency: MMKV supports concurrent read-read and read-write access between processes.
  • Easy to use. You can use MMKV as you go. Changes are saved immediately; no sync or apply calls are required.

  • Multiplatform. One Kotlin API covers Android, iOS, macOS, Linux, Windows, and JVM desktop.

Getting Started

Installation

Add the common KMP artifact to your shared module:

kotlin {
    sourceSets {
        commonMain.dependencies {
            implementation("com.tencent:mmkv-kmp:2.4.0")
        }
    }
}

For JVM desktop, the native runtime artifacts are resolved transitively. If you only ship selected desktop platforms, you can exclude unused runtimes to reduce dependency size:

kotlin {
    sourceSets {
        commonMain.dependencies {
            implementation("com.tencent:mmkv-kmp:2.4.0") {
                // Example: exclude Windows runtime from a macOS/Linux-only desktop app.
                exclude(group = "com.tencent", module = "mmkv-kmp-desktop-native-windows-x86_64")

                // Add more exclusions only for platforms your JVM desktop app will never run on.
                // exclude(group = "com.tencent", module = "mmkv-kmp-desktop-native-macos-arm64")
                // exclude(group = "com.tencent", module = "mmkv-kmp-desktop-native-macos-x86_64")
                // exclude(group = "com.tencent", module = "mmkv-kmp-desktop-native-linux-x86_64")
                // exclude(group = "com.tencent", module = "mmkv-kmp-desktop-native-linux-arm64")
            }
        }
    }
}

These exclusions do not affect Android, iOS, macOS, Linux, or Windows Kotlin/Native targets.

Supported targets

Target Status
android Supported
iosArm64, iosSimulatorArm64, iosX64 Supported
macosArm64, macosX64 Supported
linuxX64, linuxArm64, mingwX64 Supported
jvm("desktop") Supported with host-specific runtime artifact

watchOS, tvOS, visionOS, and HarmonyOS NEXT are not currently supported.

Setup

Initialize MMKV once during app startup before accessing any MMKV instance.

Android:

import android.app.Application
import com.tencent.mmkv.kmp.MMKV
import com.tencent.mmkv.kmp.initialize

class App : Application() {
    override fun onCreate() {
        super.onCreate()
        MMKV.initialize(this)
    }
}

iOS / macOS:

import com.tencent.mmkv.kmp.MMKV
import com.tencent.mmkv.kmp.initialize

fun initializeStorage() {
    MMKV.initialize()
}

JVM desktop and Kotlin/Native desktop:

import com.tencent.mmkv.kmp.MMKV
import com.tencent.mmkv.kmp.initialize

fun initializeStorage(rootDir: String) {
    MMKV.initialize(rootDir)
}

CRUD Operations

MMKV has a global default instance that can be used directly:

import com.tencent.mmkv.kmp.MMKV

val kv = MMKV.defaultMMKV()

kv.encodeBool("bool", true)
println("bool = ${kv.decodeBool("bool")}")

kv.encodeInt("int", Int.MAX_VALUE)
println("int = ${kv.decodeInt("int")}")

kv.encodeLong("long", Long.MAX_VALUE)
println("long = ${kv.decodeLong("long")}")

kv.encodeString("string", "Hello Kotlin Multiplatform from MMKV")
println("string = ${kv.decodeString("string")}")

val bytes = "Hello bytes".encodeToByteArray()
kv.encodeBytes("bytes", bytes)
println("bytes = ${kv.decodeBytes("bytes")?.decodeToString()}")

Deleting and querying:

kv.removeValueForKey("bool")
println("contains bool: ${kv.containsKey("bool")}")

kv.removeValuesForKeys(listOf("int", "long"))
println("all keys: ${kv.allKeys}")

If different modules need isolated storage, create an instance with a unique ID:

val userKv = MMKV.mmkvWithID("user_profile")
userKv.encodeString("name", "MMKV")

For multi-process access, create the instance with multi-process mode:

import com.tencent.mmkv.kmp.MMKVConfig
import com.tencent.mmkv.kmp.MMKVMode

val multiProcessKv = MMKV.mmkvWithID(
    "shared_storage",
    MMKVConfig(mode = MMKVMode.MULTI_PROCESS)
)

Supported Types

  • Primitive types:

    • Boolean, Int, Long, Float, Double
  • Classes and arrays:

    • String, ByteArray
  • Key list APIs:

    • List<String> for allKeys, allNonExpiredKeys(), and removeValuesForKeys(...)

Encryption

By default, MMKV stores key-values in plain text inside the app sandbox. Use cryptKey to create an encrypted instance:

val encrypted = MMKV.mmkvWithID(
    "secure_storage",
    MMKVConfig(cryptKey = "MyEncryptKey")
)

You can change the encryption key later, or switch an instance between encrypted and unencrypted states:

val kv = MMKV.mmkvWithID("secure_storage")

// change from unencrypted to encrypted with AES-128 key length
kv.reKey("Key_seq_1")

// change encryption key with AES-256 key length
kv.reKey("Key_Seq_Very_Looooooooong", aes256 = true)

// change from encrypted to unencrypted
kv.reKey(null)

Customize Location

You can customize the root directory during initialization. Android requires a Context; other targets use the platform-specific initialize overload without one:

// Android
MMKV.initialize(context, rootDir = "/path/to/mmkv")

// iOS, macOS, JVM desktop, Kotlin/Native desktop
MMKV.initialize(rootDir = "/path/to/mmkv")

You can also customize an individual instance location:

val kv = MMKV.mmkvWithID(
    "custom_storage",
    MMKVConfig(rootPath = "/path/to/custom/mmkv")
)

It is recommended to store MMKV files inside your app's sandbox path.

Namespace

Use MMKVNameSpace to group instances under a custom root directory:

import com.tencent.mmkv.kmp.MMKVNameSpace

val namespace = MMKVNameSpace.of("/path/to/mmkv_namespace")
val kv = namespace.mmkvWithID("profile")
kv.encodeString("name", "MMKV")

Log

By default, MMKV prints logs to the platform console. You can configure the log level during initialization:

import com.tencent.mmkv.kmp.MMKVLogLevel

MMKV.initialize(rootDir = "/path/to/mmkv", logLevel = MMKVLogLevel.None)

You can also register a handler for log redirection and MMKV callbacks on supported targets:

import com.tencent.mmkv.kmp.MMKVHandler
import com.tencent.mmkv.kmp.MMKVLogLevel

MMKV.registerHandler(object : MMKVHandler() {
    override fun wantLogRedirect(): Boolean = true

    override fun mmkvLog(
        level: MMKVLogLevel,
        file: String,
        line: Int,
        function: String,
        message: String,
    ) {
        println("[$level] $message")
    }
})

Additional docs

The sample app under KMP/sample/composeApp/ shows Android, iOS, and desktop bootstrap code.

License

MMKV is published under the BSD 3-Clause license. For details, check out the LICENSE.TXT.

Change Log

Check out the CHANGELOG.md for details of change history.

Contributing

If you are interested in contributing, check out the CONTRIBUTING.md and Code of Conduct.

FAQ & Feedback

Check out the FAQ first. If you have questions or issues, please create an issue on GitHub.