diff --git a/native/cpp/CommonCpp/NativeModules/CMakeLists.txt b/native/cpp/CommonCpp/NativeModules/CMakeLists.txt
--- a/native/cpp/CommonCpp/NativeModules/CMakeLists.txt
+++ b/native/cpp/CommonCpp/NativeModules/CMakeLists.txt
@@ -19,6 +19,7 @@
   "DraftStoreOperations.h"
   "UserStoreOperations.h"
   "KeyserverStoreOperations.h"
+  "CommunityStoreOperations.h"
 )
 
 set(NATIVE_SRCS
@@ -81,6 +82,7 @@
   ${_data_stores_path}/ReportStore.h
   ${_data_stores_path}/UserStore.h
   ${_data_stores_path}/KeyserverStore.h
+  ${_data_stores_path}/CommunityStore.h
 )
 set(DATA_STORES_SRCS
   ${_data_stores_path}/DraftStore.cpp
@@ -89,6 +91,7 @@
   ${_data_stores_path}/ReportStore.cpp
   ${_data_stores_path}/UserStore.cpp
   ${_data_stores_path}/KeyserverStore.cpp
+  ${_data_stores_path}/CommunityStore.cpp
 )
 
 set(_backup_op_path ./PersistentStorageUtilities/BackupOperationsUtilities)
diff --git a/native/cpp/CommonCpp/NativeModules/CommCoreModule.h b/native/cpp/CommonCpp/NativeModules/CommCoreModule.h
--- a/native/cpp/CommonCpp/NativeModules/CommCoreModule.h
+++ b/native/cpp/CommonCpp/NativeModules/CommCoreModule.h
@@ -4,6 +4,7 @@
 #include "../Tools/CommSecureStore.h"
 #include "../Tools/WorkerThread.h"
 #include "../_generated/commJSI.h"
+#include "PersistentStorageUtilities/DataStores/CommunityStore.h"
 #include "PersistentStorageUtilities/DataStores/DraftStore.h"
 #include "PersistentStorageUtilities/DataStores/KeyserverStore.h"
 #include "PersistentStorageUtilities/DataStores/MessageStore.h"
@@ -32,6 +33,7 @@
   ReportStore reportStore;
   UserStore userStore;
   KeyserverStore keyserverStore;
+  CommunityStore communityStore;
 
   void persistCryptoModule();
 
@@ -69,6 +71,9 @@
   virtual jsi::Value processKeyserverStoreOperations(
       jsi::Runtime &rt,
       jsi::Array operations) override;
+  virtual jsi::Value processCommunityStoreOperations(
+      jsi::Runtime &rt,
+      jsi::Array operations) override;
   virtual jsi::Value initializeCryptoAccount(jsi::Runtime &rt) override;
   virtual jsi::Value getUserPublicKey(jsi::Runtime &rt) override;
   virtual jsi::Value
diff --git a/native/cpp/CommonCpp/NativeModules/CommCoreModule.cpp b/native/cpp/CommonCpp/NativeModules/CommCoreModule.cpp
--- a/native/cpp/CommonCpp/NativeModules/CommCoreModule.cpp
+++ b/native/cpp/CommonCpp/NativeModules/CommCoreModule.cpp
@@ -311,6 +311,12 @@
   return this->keyserverStore.processStoreOperations(rt, std::move(operations));
 }
 
+jsi::Value CommCoreModule::processCommunityStoreOperations(
+    jsi::Runtime &rt,
+    jsi::Array operations) {
+  return this->communityStore.processStoreOperations(rt, std::move(operations));
+}
+
 void CommCoreModule::terminate(jsi::Runtime &rt) {
   TerminateApp::terminate();
 }
@@ -1051,7 +1057,8 @@
       messageStore(jsInvoker),
       reportStore(jsInvoker),
       userStore(jsInvoker),
-      keyserverStore(jsInvoker) {
+      keyserverStore(jsInvoker),
+      communityStore(jsInvoker) {
   GlobalDBSingleton::instance.enableMultithreading();
 }
 
diff --git a/native/cpp/CommonCpp/NativeModules/CommunityStoreOperations.h b/native/cpp/CommonCpp/NativeModules/CommunityStoreOperations.h
new file mode 100644
--- /dev/null
+++ b/native/cpp/CommonCpp/NativeModules/CommunityStoreOperations.h
@@ -0,0 +1,48 @@
+#pragma once
+
+#include "../DatabaseManagers/entities/CommunityInfo.h"
+#include "DatabaseManager.h"
+#include <vector>
+
+namespace comm {
+class CommunityStoreOperationBase {
+public:
+  virtual void execute() = 0;
+  virtual ~CommunityStoreOperationBase(){};
+};
+
+class RemoveCommunitiesOperation : public CommunityStoreOperationBase {
+public:
+  RemoveCommunitiesOperation(std::vector<std::string> ids) : ids{ids} {
+  }
+
+  virtual void execute() override {
+    DatabaseManager::getQueryExecutor().removeCommunities(this->ids);
+  }
+
+private:
+  std::vector<std::string> ids;
+};
+
+class ReplaceCommunityOperation : public CommunityStoreOperationBase {
+public:
+  ReplaceCommunityOperation(CommunityInfo &&community)
+      : community{std::move(community)} {
+  }
+
+  virtual void execute() override {
+    DatabaseManager::getQueryExecutor().replaceCommunity(this->community);
+  }
+
+private:
+  CommunityInfo community;
+};
+
+class RemoveAllCommunitiesOperation : public CommunityStoreOperationBase {
+public:
+  virtual void execute() override {
+    DatabaseManager::getQueryExecutor().removeAllCommunities();
+  }
+};
+
+} // namespace comm
diff --git a/native/cpp/CommonCpp/NativeModules/PersistentStorageUtilities/DataStores/CommunityStore.h b/native/cpp/CommonCpp/NativeModules/PersistentStorageUtilities/DataStores/CommunityStore.h
new file mode 100644
--- /dev/null
+++ b/native/cpp/CommonCpp/NativeModules/PersistentStorageUtilities/DataStores/CommunityStore.h
@@ -0,0 +1,30 @@
+#pragma once
+
+#include "../../../DatabaseManagers/entities/CommunityInfo.h"
+#include "BaseDataStore.h"
+#include "CommunityStoreOperations.h"
+
+#include <jsi/jsi.h>
+
+namespace comm {
+
+class CommunityStore
+    : public BaseDataStore<CommunityStoreOperationBase, CommunityInfo> {
+private:
+  static OperationType REMOVE_OPERATION;
+  static OperationType REMOVE_ALL_OPERATION;
+  static OperationType REPLACE_OPERATION;
+
+public:
+  CommunityStore(std::shared_ptr<facebook::react::CallInvoker> jsInvoker);
+
+  std::vector<std::unique_ptr<CommunityStoreOperationBase>> createOperations(
+      jsi::Runtime &rt,
+      const jsi::Array &operations) const override;
+
+  jsi::Array parseDBDataStore(
+      jsi::Runtime &rt,
+      std::shared_ptr<std::vector<CommunityInfo>> dataVectorPtr) const override;
+};
+
+} // namespace comm
diff --git a/native/cpp/CommonCpp/NativeModules/PersistentStorageUtilities/DataStores/CommunityStore.cpp b/native/cpp/CommonCpp/NativeModules/PersistentStorageUtilities/DataStores/CommunityStore.cpp
new file mode 100644
--- /dev/null
+++ b/native/cpp/CommonCpp/NativeModules/PersistentStorageUtilities/DataStores/CommunityStore.cpp
@@ -0,0 +1,67 @@
+#include "CommunityStore.h"
+
+#include <ReactCommon/TurboModuleUtils.h>
+#include <jsi/jsi.h>
+
+namespace comm {
+
+OperationType CommunityStore::REMOVE_OPERATION = "remove_communities";
+OperationType CommunityStore::REMOVE_ALL_OPERATION = "remove_all_communities";
+OperationType CommunityStore::REPLACE_OPERATION = "replace_community";
+
+CommunityStore::CommunityStore(
+    std::shared_ptr<facebook::react::CallInvoker> jsInvoker)
+    : BaseDataStore(jsInvoker) {
+}
+
+jsi::Array CommunityStore::parseDBDataStore(
+    jsi::Runtime &rt,
+    std::shared_ptr<std::vector<CommunityInfo>> communitiesVectorPtr) const {
+  jsi::Array jsiCommunities = jsi::Array(rt, 0);
+  return jsiCommunities;
+}
+
+std::vector<std::unique_ptr<CommunityStoreOperationBase>>
+CommunityStore::createOperations(jsi::Runtime &rt, const jsi::Array &operations)
+    const {
+  std::vector<std::unique_ptr<CommunityStoreOperationBase>> communityStoreOps;
+
+  for (size_t idx = 0; idx < operations.size(rt); idx++) {
+    jsi::Object op = operations.getValueAtIndex(rt, idx).asObject(rt);
+    std::string opType = op.getProperty(rt, "type").asString(rt).utf8(rt);
+
+    if (opType == REMOVE_OPERATION) {
+      std::vector<std::string> communityIDsToRemove;
+      jsi::Object payloadObj = op.getProperty(rt, "payload").asObject(rt);
+      jsi::Array communityIDs =
+          payloadObj.getProperty(rt, "ids").asObject(rt).asArray(rt);
+      for (int communityIdx = 0; communityIdx < communityIDs.size(rt);
+           communityIdx++) {
+        communityIDsToRemove.push_back(
+            communityIDs.getValueAtIndex(rt, communityIdx)
+                .asString(rt)
+                .utf8(rt));
+      }
+      communityStoreOps.push_back(std::make_unique<RemoveCommunitiesOperation>(
+          std::move(communityIDsToRemove)));
+    } else if (opType == REMOVE_ALL_OPERATION) {
+      communityStoreOps.push_back(
+          std::make_unique<RemoveAllCommunitiesOperation>());
+    } else if (opType == REPLACE_OPERATION) {
+      jsi::Object payloadObj = op.getProperty(rt, "payload").asObject(rt);
+      std::string id = payloadObj.getProperty(rt, "id").asString(rt).utf8(rt);
+      std::string community_info =
+          payloadObj.getProperty(rt, "communityInfo").asString(rt).utf8(rt);
+
+      CommunityInfo community{id, community_info};
+
+      communityStoreOps.push_back(
+          std::make_unique<ReplaceCommunityOperation>(std::move(community)));
+    } else {
+      throw std::runtime_error("unsupported operation: " + opType);
+    }
+  };
+  return communityStoreOps;
+}
+
+} // namespace comm
diff --git a/native/cpp/CommonCpp/_generated/commJSI-generated.cpp b/native/cpp/CommonCpp/_generated/commJSI-generated.cpp
--- a/native/cpp/CommonCpp/_generated/commJSI-generated.cpp
+++ b/native/cpp/CommonCpp/_generated/commJSI-generated.cpp
@@ -63,6 +63,9 @@
 static jsi::Value __hostFunction_CommCoreModuleSchemaCxxSpecJSI_processKeyserverStoreOperations(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) {
   return static_cast<CommCoreModuleSchemaCxxSpecJSI *>(&turboModule)->processKeyserverStoreOperations(rt, args[0].asObject(rt).asArray(rt));
 }
+static jsi::Value __hostFunction_CommCoreModuleSchemaCxxSpecJSI_processCommunityStoreOperations(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) {
+  return static_cast<CommCoreModuleSchemaCxxSpecJSI *>(&turboModule)->processCommunityStoreOperations(rt, args[0].asObject(rt).asArray(rt));
+}
 static jsi::Value __hostFunction_CommCoreModuleSchemaCxxSpecJSI_initializeCryptoAccount(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) {
   return static_cast<CommCoreModuleSchemaCxxSpecJSI *>(&turboModule)->initializeCryptoAccount(rt);
 }
@@ -179,6 +182,7 @@
   methodMap_["processThreadStoreOperationsSync"] = MethodMetadata {1, __hostFunction_CommCoreModuleSchemaCxxSpecJSI_processThreadStoreOperationsSync};
   methodMap_["processUserStoreOperations"] = MethodMetadata {1, __hostFunction_CommCoreModuleSchemaCxxSpecJSI_processUserStoreOperations};
   methodMap_["processKeyserverStoreOperations"] = MethodMetadata {1, __hostFunction_CommCoreModuleSchemaCxxSpecJSI_processKeyserverStoreOperations};
+  methodMap_["processCommunityStoreOperations"] = MethodMetadata {1, __hostFunction_CommCoreModuleSchemaCxxSpecJSI_processCommunityStoreOperations};
   methodMap_["initializeCryptoAccount"] = MethodMetadata {0, __hostFunction_CommCoreModuleSchemaCxxSpecJSI_initializeCryptoAccount};
   methodMap_["getUserPublicKey"] = MethodMetadata {0, __hostFunction_CommCoreModuleSchemaCxxSpecJSI_getUserPublicKey};
   methodMap_["getOneTimeKeys"] = MethodMetadata {1, __hostFunction_CommCoreModuleSchemaCxxSpecJSI_getOneTimeKeys};
diff --git a/native/cpp/CommonCpp/_generated/commJSI.h b/native/cpp/CommonCpp/_generated/commJSI.h
--- a/native/cpp/CommonCpp/_generated/commJSI.h
+++ b/native/cpp/CommonCpp/_generated/commJSI.h
@@ -36,6 +36,7 @@
   virtual void processThreadStoreOperationsSync(jsi::Runtime &rt, jsi::Array operations) = 0;
   virtual jsi::Value processUserStoreOperations(jsi::Runtime &rt, jsi::Array operations) = 0;
   virtual jsi::Value processKeyserverStoreOperations(jsi::Runtime &rt, jsi::Array operations) = 0;
+  virtual jsi::Value processCommunityStoreOperations(jsi::Runtime &rt, jsi::Array operations) = 0;
   virtual jsi::Value initializeCryptoAccount(jsi::Runtime &rt) = 0;
   virtual jsi::Value getUserPublicKey(jsi::Runtime &rt) = 0;
   virtual jsi::Value getOneTimeKeys(jsi::Runtime &rt, double oneTimeKeysAmount) = 0;
@@ -216,6 +217,14 @@
       return bridging::callFromJs<jsi::Value>(
           rt, &T::processKeyserverStoreOperations, jsInvoker_, instance_, std::move(operations));
     }
+    jsi::Value processCommunityStoreOperations(jsi::Runtime &rt, jsi::Array operations) override {
+      static_assert(
+          bridging::getParameterCount(&T::processCommunityStoreOperations) == 2,
+          "Expected processCommunityStoreOperations(...) to have 2 parameters");
+
+      return bridging::callFromJs<jsi::Value>(
+          rt, &T::processCommunityStoreOperations, jsInvoker_, instance_, std::move(operations));
+    }
     jsi::Value initializeCryptoAccount(jsi::Runtime &rt) override {
       static_assert(
           bridging::getParameterCount(&T::initializeCryptoAccount) == 1,
diff --git a/native/ios/Comm.xcodeproj/project.pbxproj b/native/ios/Comm.xcodeproj/project.pbxproj
--- a/native/ios/Comm.xcodeproj/project.pbxproj
+++ b/native/ios/Comm.xcodeproj/project.pbxproj
@@ -55,6 +55,7 @@
 		8EF7756B2A7433630046A385 /* ThreadStore.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8EF775692A7433630046A385 /* ThreadStore.cpp */; };
 		8EF7756E2A7513F40046A385 /* MessageStore.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8EF7756D2A7513F40046A385 /* MessageStore.cpp */; };
 		8EF775712A751B780046A385 /* ReportStore.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8EF7756F2A751B780046A385 /* ReportStore.cpp */; };
+		B3B02EBF2B8538980020D118 /* CommunityStore.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B3B02EBD2B8536560020D118 /* CommunityStore.cpp */; };
 		B71AFF1F265EDD8600B22352 /* IBMPlexSans-Medium.ttf in Resources */ = {isa = PBXBuildFile; fileRef = B71AFF1E265EDD8600B22352 /* IBMPlexSans-Medium.ttf */; };
 		CB01F0C22B67EF5A0089E1F9 /* SQLiteDataConverters.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CB01F0C12B67EF470089E1F9 /* SQLiteDataConverters.cpp */; };
 		CB01F0C42B67F3A10089E1F9 /* SQLiteStatementWrapper.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CB01F0C32B67F3970089E1F9 /* SQLiteStatementWrapper.cpp */; };
@@ -235,6 +236,9 @@
 		8EF775702A751B780046A385 /* ReportStore.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ReportStore.h; path = PersistentStorageUtilities/DataStores/ReportStore.h; sourceTree = "<group>"; };
 		913E5A7BDECB327E3DE11053 /* Pods-NotificationService.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-NotificationService.release.xcconfig"; path = "Target Support Files/Pods-NotificationService/Pods-NotificationService.release.xcconfig"; sourceTree = "<group>"; };
 		994BEBDD4E4959F69CEA0BC3 /* libPods-Comm.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Comm.a"; sourceTree = BUILT_PRODUCTS_DIR; };
+		B3B02EBC2B8534C00020D118 /* CommunityStore.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = CommunityStore.h; path = PersistentStorageUtilities/DataStores/CommunityStore.h; sourceTree = "<group>"; };
+		B3B02EBD2B8536560020D118 /* CommunityStore.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = CommunityStore.cpp; path = PersistentStorageUtilities/DataStores/CommunityStore.cpp; sourceTree = "<group>"; };
+		B3B02EBE2B8538860020D118 /* CommunityStoreOperations.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CommunityStoreOperations.h; sourceTree = "<group>"; };
 		B7055C6B26E477CF00BE0548 /* MessageStoreOperations.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MessageStoreOperations.h; sourceTree = "<group>"; };
 		B70FBC1226B047050040F480 /* Message.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Message.h; sourceTree = "<group>"; };
 		B71AFF1E265EDD8600B22352 /* IBMPlexSans-Medium.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; name = "IBMPlexSans-Medium.ttf"; path = "Resources/IBMPlexSans-Medium.ttf"; sourceTree = "<group>"; };
@@ -453,6 +457,7 @@
 		71BE843A2636A944002849D2 /* NativeModules */ = {
 			isa = PBXGroup;
 			children = (
+				B3B02EBE2B8538860020D118 /* CommunityStoreOperations.h */,
 				8E2CC2562B5C999A000C94D6 /* KeyserverStoreOperations.h */,
 				CBA784382B28AC4300E9F419 /* CommServicesAuthMetadataEmitter.h */,
 				8E3994562B039A9300D5E950 /* UserStoreOperations.h */,
@@ -631,6 +636,8 @@
 			children = (
 				8E2CC2582B5C99B0000C94D6 /* KeyserverStore.cpp */,
 				8E2CC2572B5C99B0000C94D6 /* KeyserverStore.h */,
+				B3B02EBD2B8536560020D118 /* CommunityStore.cpp */,
+				B3B02EBC2B8534C00020D118 /* CommunityStore.h */,
 				8E3994532B039A7C00D5E950 /* UserStore.cpp */,
 				8E3994542B039A7C00D5E950 /* UserStore.h */,
 				8EF7756F2A751B780046A385 /* ReportStore.cpp */,
@@ -1120,6 +1127,7 @@
 				7F0C6E31291C4468002AA2D9 /* ExpoModulesProvider.swift in Sources */,
 				8EF775682A74032C0046A385 /* CommRustModule.cpp in Sources */,
 				8E43C32C291E5B4A009378F5 /* TerminateApp.mm in Sources */,
+				B3B02EBF2B8538980020D118 /* CommunityStore.cpp in Sources */,
 				8BC9568529FC49B00060AE4A /* JSIRust.cpp in Sources */,
 				8EA59BD92A73DAB000EB4F53 /* rustJSI-generated.cpp in Sources */,
 				CB38B48628771CDD00171182 /* TemporaryMessageStorage.mm in Sources */,
diff --git a/native/schema/CommCoreModuleSchema.js b/native/schema/CommCoreModuleSchema.js
--- a/native/schema/CommCoreModuleSchema.js
+++ b/native/schema/CommCoreModuleSchema.js
@@ -5,6 +5,7 @@
 import { TurboModuleRegistry } from 'react-native';
 import type { TurboModule } from 'react-native/Libraries/TurboModule/RCTExport.js';
 
+import type { ClientDBCommunityStoreOperation } from 'lib/ops/community-store-ops.js';
 import type { ClientDBKeyserverStoreOperation } from 'lib/ops/keyserver-store-ops';
 import type { ClientDBMessageStoreOperation } from 'lib/ops/message-store-ops.js';
 import type { ClientDBReportStoreOperation } from 'lib/ops/report-store-ops.js';
@@ -70,6 +71,9 @@
   +processKeyserverStoreOperations: (
     operations: $ReadOnlyArray<ClientDBKeyserverStoreOperation>,
   ) => Promise<void>;
+  +processCommunityStoreOperations: (
+    operations: $ReadOnlyArray<ClientDBCommunityStoreOperation>,
+  ) => Promise<void>;
   +initializeCryptoAccount: () => Promise<string>;
   +getUserPublicKey: () => Promise<ClientPublicKeys>;
   +getOneTimeKeys: (oneTimeKeysAmount: number) => Promise<OneTimeKeysResult>;