diff --git a/native/android/app/src/cpp/CommMMKV.cpp b/native/android/app/src/cpp/CommMMKV.cpp
--- a/native/android/app/src/cpp/CommMMKV.cpp
+++ b/native/android/app/src/cpp/CommMMKV.cpp
@@ -37,6 +37,53 @@
     }
     return std::nullopt;
   }
+
+  static bool setInt(std::string key, int value) {
+    static const auto cls = javaClassStatic();
+    static auto method =
+        cls->getStaticMethod<jboolean(std::string, int)>("setInt");
+    return method(cls, key, value);
+  }
+
+  static std::optional<int> getInt(std::string key, int noValue) {
+    static const auto cls = javaClassStatic();
+    static auto method =
+        cls->getStaticMethod<JInteger(std::string, int)>("getInt");
+    const auto result = method(cls, key, noValue);
+    if (result) {
+      return result->value();
+    }
+    return std::nullopt;
+  }
+
+  static std::vector<std::string> getAllKeys() {
+    static const auto cls = javaClassStatic();
+    static auto method =
+        cls->getStaticMethod<JArrayClass<JString>()>("getAllKeys");
+    auto methodResult = method(cls);
+
+    std::vector<std::string> result;
+    for (int i = 0; i < methodResult->size(); i++) {
+      result.push_back(methodResult->getElement(i)->toStdString());
+    }
+
+    return result;
+  }
+
+  static void removeKeys(const std::vector<std::string> &keys) {
+    static const auto cls = javaClassStatic();
+    static auto method =
+        cls->getStaticMethod<void(local_ref<JArrayClass<JString>>)>(
+            "removeKeys");
+
+    local_ref<JArrayClass<JString>> keysJava =
+        JArrayClass<JString>::newArray(keys.size());
+
+    for (int i = 0; i < keys.size(); i++) {
+      keysJava->setElement(i, *make_jstring(keys[i]));
+    }
+    method(cls, keysJava);
+  }
 };
 
 namespace comm {
@@ -65,4 +112,29 @@
   return result;
 }
 
+bool CommMMKV::setInt(std::string key, int value) {
+  bool result;
+  NativeAndroidAccessProvider::runTask(
+      [&]() { result = CommMMKVJavaClass::setInt(key, value); });
+  return result;
+}
+
+std::optional<int> CommMMKV::getInt(std::string key, int noValue) {
+  std::optional<int> result;
+  NativeAndroidAccessProvider::runTask(
+      [&]() { result = CommMMKVJavaClass::getInt(key, noValue); });
+  return result;
+}
+
+std::vector<std::string> CommMMKV::getAllKeys() {
+  std::vector<std::string> result;
+  NativeAndroidAccessProvider::runTask(
+      [&]() { result = CommMMKVJavaClass::getAllKeys(); });
+  return result;
+}
+
+void CommMMKV::removeKeys(const std::vector<std::string> &keys) {
+  NativeAndroidAccessProvider::runTask(
+      [&]() { CommMMKVJavaClass::removeKeys(keys); });
+}
 } // namespace comm
diff --git a/native/android/app/src/main/java/app/comm/android/fbjni/CommMMKV.java b/native/android/app/src/main/java/app/comm/android/fbjni/CommMMKV.java
--- a/native/android/app/src/main/java/app/comm/android/fbjni/CommMMKV.java
+++ b/native/android/app/src/main/java/app/comm/android/fbjni/CommMMKV.java
@@ -95,4 +95,31 @@
     initialize();
     return getMMKVInstance(mmkvIdentifier, mmkvEncryptionKey).decodeString(key);
   }
+
+  public static boolean setInt(String key, int value) {
+    initialize();
+    return getMMKVInstance(mmkvIdentifier, mmkvEncryptionKey)
+        .encode(key, value);
+  }
+
+  public static Integer getInt(String key, int noValue) {
+    initialize();
+    int value = getMMKVInstance(mmkvIdentifier, mmkvEncryptionKey)
+                    .decodeInt(key, noValue);
+    if (value == noValue) {
+      return null;
+    }
+    return value;
+  }
+
+  public static String[] getAllKeys() {
+    initialize();
+    return getMMKVInstance(mmkvIdentifier, mmkvEncryptionKey).allKeys();
+  }
+
+  public static void removeKeys(String[] keys) {
+    initialize();
+    getMMKVInstance(mmkvIdentifier, mmkvEncryptionKey)
+        .removeValuesForKeys(keys);
+  }
 }
diff --git a/native/cpp/CommonCpp/Tools/CommMMKV.h b/native/cpp/CommonCpp/Tools/CommMMKV.h
--- a/native/cpp/CommonCpp/Tools/CommMMKV.h
+++ b/native/cpp/CommonCpp/Tools/CommMMKV.h
@@ -2,6 +2,7 @@
 
 #include <optional>
 #include <string>
+#include <vector>
 
 namespace comm {
 class CommMMKV {
@@ -11,5 +12,19 @@
   static void clearSensitiveData();
   static bool setString(std::string key, std::string value);
   static std::optional<std::string> getString(std::string key);
+
+  static bool setInt(std::string key, int value);
+
+  // MMKV API can't return null when we try to get integer that
+  // doesn't exist. It allows us to set default value that is
+  // returned instead in case the integer isn't present. The
+  // developer should pass as `noValue` the value that they
+  // know should never be set under certain key. Implementation
+  // will pass `noValue` as default value and return `std::nullopt`
+  // in case MMKV returns default value.
+  static std::optional<int> getInt(std::string key, int noValue);
+
+  static std::vector<std::string> getAllKeys();
+  static void removeKeys(const std::vector<std::string> &keys);
 };
 } // namespace comm
diff --git a/native/ios/Comm/CommMMKV.mm b/native/ios/Comm/CommMMKV.mm
--- a/native/ios/Comm/CommMMKV.mm
+++ b/native/ios/Comm/CommMMKV.mm
@@ -130,4 +130,62 @@
   return std::string([value UTF8String]);
 }
 
+bool CommMMKV::setInt(std::string key, int value) {
+  CommMMKV::initialize();
+  MMKV *mmkv = getMMKVInstance(mmkvIdentifier, mmkvEncryptionKey);
+
+  BOOL result =
+      [mmkv setInt64:value
+              forKey:[NSString stringWithCString:key.c_str()
+                                        encoding:NSUTF8StringEncoding]];
+
+  if (!result) {
+    Logger::log("Attempt to write in background or failure during write.");
+  }
+  return result;
+}
+
+std::optional<int> CommMMKV::getInt(std::string key, int noValue) {
+  CommMMKV::initialize();
+  MMKV *mmkv = getMMKVInstance(mmkvIdentifier, mmkvEncryptionKey);
+
+  int value =
+      [mmkv getInt64ForKey:[NSString stringWithCString:key.c_str()
+                                              encoding:NSUTF8StringEncoding]
+              defaultValue:noValue
+                  hasValue:nil];
+
+  if (value == noValue) {
+    return std::nullopt;
+  }
+
+  return value;
+}
+
+std::vector<std::string> CommMMKV::getAllKeys() {
+  CommMMKV::initialize();
+  MMKV *mmkv = getMMKVInstance(mmkvIdentifier, mmkvEncryptionKey);
+
+  NSArray<NSString *> *allKeys = [mmkv allKeys];
+  std::vector<std::string> result;
+
+  for (NSString *key in allKeys) {
+    result.emplace_back(std::string([key UTF8String]));
+  }
+
+  return result;
+}
+
+void CommMMKV::removeKeys(const std::vector<std::string> &keys) {
+  CommMMKV::initialize();
+  MMKV *mmkv = getMMKVInstance(mmkvIdentifier, mmkvEncryptionKey);
+
+  NSMutableArray<NSString *> *keysObjC = [[NSMutableArray alloc] init];
+  for (const auto &key : keys) {
+    [keysObjC addObject:[NSString stringWithCString:key.c_str()
+                                           encoding:NSUTF8StringEncoding]];
+  }
+  [mmkv removeValuesForKeys:keysObjC];
+}
+
 } // namespace comm