diff --git a/lib/reducers/community-reducer.js b/lib/reducers/community-reducer.js
new file mode 100644
--- /dev/null
+++ b/lib/reducers/community-reducer.js
@@ -0,0 +1,42 @@
+// @flow
+
+import { addCommunityActionType } from '../actions/community-actions.js';
+import {
+  communityStoreOpsHandlers,
+  type CommunityStoreOperation,
+  type ReplaceCommunityOperation,
+} from '../ops/community-store-ops.js';
+import type { CommunityStore } from '../types/community-types.js';
+import type { BaseAction } from '../types/redux-types';
+
+const { processStoreOperations: processStoreOps } = communityStoreOpsHandlers;
+
+function reduceCommunityStore(
+  state: CommunityStore,
+  action: BaseAction,
+): {
+  +communityStore: CommunityStore,
+  +communityStoreOperations: $ReadOnlyArray<CommunityStoreOperation>,
+} {
+  if (action.type === addCommunityActionType) {
+    const replaceOperation: ReplaceCommunityOperation = {
+      type: 'replace_community',
+      payload: {
+        id: action.payload.id,
+        communityInfo: action.payload.newCommunityInfo,
+      },
+    };
+
+    return {
+      communityStore: processStoreOps(state, [replaceOperation]),
+      communityStoreOperations: [replaceOperation],
+    };
+  }
+
+  return {
+    communityStore: state,
+    communityStoreOperations: [],
+  };
+}
+
+export { reduceCommunityStore };
diff --git a/lib/reducers/master-reducer.js b/lib/reducers/master-reducer.js
--- a/lib/reducers/master-reducer.js
+++ b/lib/reducers/master-reducer.js
@@ -1,6 +1,7 @@
 // @flow
 
 import reduceCalendarFilters from './calendar-filters-reducer.js';
+import { reduceCommunityStore } from './community-reducer.js';
 import reduceCustomerServer from './custom-server-reducer.js';
 import reduceDataLoaded from './data-loaded-reducer.js';
 import { reduceDraftStore } from './draft-reducer.js';
@@ -155,6 +156,11 @@
     newInconsistencies,
   );
 
+  const { communityStore, communityStoreOperations } = reduceCommunityStore(
+    state.communityStore,
+    action,
+  );
+
   return {
     state: {
       ...state,
@@ -199,6 +205,7 @@
       ),
       globalThemeInfo: reduceGlobalThemeInfo(state.globalThemeInfo, action),
       customServer: reduceCustomerServer(state.customServer, action),
+      communityStore,
     },
     storeOperations: {
       draftStoreOperations,
@@ -207,6 +214,7 @@
       reportStoreOperations,
       userStoreOperations,
       keyserverStoreOperations,
+      communityStoreOperations,
     },
   };
 }
diff --git a/lib/types/redux-types.js b/lib/types/redux-types.js
--- a/lib/types/redux-types.js
+++ b/lib/types/redux-types.js
@@ -19,7 +19,7 @@
   UpdateUserAvatarRequest,
   UpdateUserAvatarResponse,
 } from './avatar-types.js';
-import type { AddCommunityPayload } from './community-types.js';
+import type { CommunityStore, AddCommunityPayload } from './community-types.js';
 import type { CryptoStore } from './crypto-types.js';
 import type {
   GetVersionActionPayload,
@@ -155,6 +155,7 @@
   +integrityStore: IntegrityStore,
   +globalThemeInfo: GlobalThemeInfo,
   +customServer: ?string,
+  +communityStore: CommunityStore,
   ...
 };
 
diff --git a/lib/types/store-ops-types.js b/lib/types/store-ops-types.js
--- a/lib/types/store-ops-types.js
+++ b/lib/types/store-ops-types.js
@@ -16,6 +16,7 @@
 import type {
   ClientDBCommunityInfo,
   ClientDBCommunityStoreOperation,
+  CommunityStoreOperation,
 } from '../ops/community-store-ops.js';
 import type {
   ClientDBKeyserverInfo,
@@ -47,6 +48,7 @@
   +reportStoreOperations: $ReadOnlyArray<ReportStoreOperation>,
   +userStoreOperations: $ReadOnlyArray<UserStoreOperation>,
   +keyserverStoreOperations: $ReadOnlyArray<KeyserverStoreOperation>,
+  +communityStoreOperations: $ReadOnlyArray<CommunityStoreOperation>,
 };
 
 export type ClientDBStoreOperations = {
diff --git a/lib/utils/reducers-utils.test.js b/lib/utils/reducers-utils.test.js
--- a/lib/utils/reducers-utils.test.js
+++ b/lib/utils/reducers-utils.test.js
@@ -81,6 +81,9 @@
       integrityStore: { threadHashes: {}, threadHashingStatus: 'starting' },
       globalThemeInfo: defaultGlobalThemeInfo,
       customServer: null,
+      communityStore: {
+        communityInfos: {},
+      },
     };
     state = {
       ...defaultState,
diff --git a/native/redux/default-state.js b/native/redux/default-state.js
--- a/native/redux/default-state.js
+++ b/native/redux/default-state.js
@@ -81,6 +81,9 @@
   },
   threadActivityStore: {},
   integrityStore: { threadHashes: {}, threadHashingStatus: 'starting' },
+  communityStore: {
+    communityInfos: {},
+  },
 }: AppState);
 
 export { defaultState };
diff --git a/native/redux/redux-setup.js b/native/redux/redux-setup.js
--- a/native/redux/redux-setup.js
+++ b/native/redux/redux-setup.js
@@ -288,6 +288,7 @@
     reportStoreOperations,
     userStoreOperations,
     keyserverStoreOperations,
+    communityStoreOperations,
   } = storeOperations;
 
   const fixUnreadActiveThreadResult = fixUnreadActiveThread(state, action);
@@ -305,6 +306,7 @@
     reportStoreOperations,
     userStoreOperations,
     keyserverStoreOperations,
+    communityStoreOperations,
   });
 
   return state;
diff --git a/native/redux/redux-utils.js b/native/redux/redux-utils.js
--- a/native/redux/redux-utils.js
+++ b/native/redux/redux-utils.js
@@ -2,6 +2,7 @@
 
 import { useSelector as reactReduxUseSelector } from 'react-redux';
 
+import { communityStoreOpsHandlers } from 'lib/ops/community-store-ops.js';
 import { keyserverStoreOpsHandlers } from 'lib/ops/keyserver-store-ops.js';
 import { messageStoreOpsHandlers } from 'lib/ops/message-store-ops.js';
 import { reportStoreOpsHandlers } from 'lib/ops/report-store-ops.js';
@@ -30,6 +31,7 @@
     reportStoreOperations,
     userStoreOperations,
     keyserverStoreOperations,
+    communityStoreOperations,
   } = storeOperations;
 
   const convertedThreadStoreOperations =
@@ -42,6 +44,8 @@
     userStoreOpsHandlers.convertOpsToClientDBOps(userStoreOperations);
   const convertedKeyserverStoreOperations =
     keyserverStoreOpsHandlers.convertOpsToClientDBOps(keyserverStoreOperations);
+  const convertedCommunityStoreOperations =
+    communityStoreOpsHandlers.convertOpsToClientDBOps(communityStoreOperations);
 
   try {
     const promises = [];
@@ -83,6 +87,13 @@
         ),
       );
     }
+    if (convertedCommunityStoreOperations.length > 0) {
+      promises.push(
+        commCoreModule.processCommunityStoreOperations(
+          convertedCommunityStoreOperations,
+        ),
+      );
+    }
     await Promise.all(promises);
   } catch (e) {
     if (isTaskCancelledError(e)) {
diff --git a/native/redux/state-types.js b/native/redux/state-types.js
--- a/native/redux/state-types.js
+++ b/native/redux/state-types.js
@@ -3,6 +3,7 @@
 import type { Orientations } from 'react-native-orientation-locker';
 import type { PersistState } from 'redux-persist/es/types.js';
 
+import type { CommunityStore } from 'lib/types/community-types.js';
 import type { DraftStore } from 'lib/types/draft-types.js';
 import type { EnabledApps } from 'lib/types/enabled-apps.js';
 import type { EntryStore } from 'lib/types/entry-types.js';
@@ -75,6 +76,7 @@
   +threadActivityStore: ThreadActivityStore,
   +localSettings: LocalSettings,
   +integrityStore: IntegrityStore,
+  +communityStore: CommunityStore,
 };
 
 export { nonUserSpecificFieldsNative };
diff --git a/web/database/utils/store.js b/web/database/utils/store.js
--- a/web/database/utils/store.js
+++ b/web/database/utils/store.js
@@ -1,5 +1,6 @@
 // @flow
 
+import { communityStoreOpsHandlers } from 'lib/ops/community-store-ops.js';
 import { keyserverStoreOpsHandlers } from 'lib/ops/keyserver-store-ops.js';
 import { reportStoreOpsHandlers } from 'lib/ops/report-store-ops.js';
 import { threadStoreOpsHandlers } from 'lib/ops/thread-store-ops.js';
@@ -70,6 +71,7 @@
     threadStoreOperations,
     reportStoreOperations,
     keyserverStoreOperations,
+    communityStoreOperations,
   } = storeOperations;
 
   const canUseDatabase = canUseDatabaseOnWeb(userID);
@@ -81,12 +83,15 @@
     reportStoreOpsHandlers.convertOpsToClientDBOps(reportStoreOperations);
   const convertedKeyserverStoreOperations =
     keyserverStoreOpsHandlers.convertOpsToClientDBOps(keyserverStoreOperations);
+  const convertedCommunityStoreOperations =
+    communityStoreOpsHandlers.convertOpsToClientDBOps(communityStoreOperations);
 
   if (
     convertedThreadStoreOperations.length === 0 &&
     convertedReportStoreOperations.length === 0 &&
     draftStoreOperations.length === 0 &&
-    convertedKeyserverStoreOperations.length === 0
+    convertedKeyserverStoreOperations.length === 0 &&
+    convertedCommunityStoreOperations.length === 0
   ) {
     return;
   }
@@ -104,6 +109,7 @@
         reportStoreOperations: convertedReportStoreOperations,
         threadStoreOperations: convertedThreadStoreOperations,
         keyserverStoreOperations: convertedKeyserverStoreOperations,
+        communityStoreOperations: convertedCommunityStoreOperations,
       },
     });
   } catch (e) {
diff --git a/web/redux/default-state.js b/web/redux/default-state.js
--- a/web/redux/default-state.js
+++ b/web/redux/default-state.js
@@ -78,6 +78,9 @@
   integrityStore: { threadHashes: {}, threadHashingStatus: 'starting' },
   globalThemeInfo: defaultGlobalThemeInfo,
   customServer: null,
+  communityStore: {
+    communityInfos: {},
+  },
 });
 
 export { defaultWebState };
diff --git a/web/redux/initial-state-gate.js b/web/redux/initial-state-gate.js
--- a/web/redux/initial-state-gate.js
+++ b/web/redux/initial-state-gate.js
@@ -124,6 +124,7 @@
             reportStoreOperations: [],
             userStoreOperations: [],
             keyserverStoreOperations: [],
+            communityStoreOperations: [],
           },
           currentLoggedInUserID,
         );
diff --git a/web/redux/redux-setup.js b/web/redux/redux-setup.js
--- a/web/redux/redux-setup.js
+++ b/web/redux/redux-setup.js
@@ -26,6 +26,7 @@
   invalidSessionDowngrade,
   identityInvalidSessionDowngrade,
 } from 'lib/shared/session-utils.js';
+import type { CommunityStore } from 'lib/types/community-types.js';
 import type { CryptoStore } from 'lib/types/crypto-types.js';
 import type { DraftStore } from 'lib/types/draft-types.js';
 import type { EnabledApps } from 'lib/types/enabled-apps.js';
@@ -117,6 +118,7 @@
   +integrityStore: IntegrityStore,
   +globalThemeInfo: GlobalThemeInfo,
   +customServer: ?string,
+  +communityStore: CommunityStore,
 };
 
 export type Action =
@@ -143,6 +145,7 @@
     reportStoreOperations: [],
     userStoreOperations: [],
     keyserverStoreOperations: [],
+    communityStoreOperations: [],
   };
 
   if (action.type === setInitialReduxState) {