diff --git a/lib/utils/drawer-utils.react.js b/lib/utils/drawer-utils.react.js
new file mode 100644
--- /dev/null
+++ b/lib/utils/drawer-utils.react.js
@@ -0,0 +1,84 @@
+// @flow
+
+import { threadIsChannel } from '../shared/thread-utils.js';
+import {
+  type ThreadInfo,
+  type ResolvedThreadInfo,
+  communitySubthreads,
+} from '../types/thread-types.js';
+
+export type CommunityDrawerItemData<T> = {
+  +threadInfo: ThreadInfo,
+  +itemChildren?: $ReadOnlyArray<CommunityDrawerItemData<T>>,
+  +hasSubchannelsButton: boolean,
+  +labelStyle: T,
+};
+
+function createRecursiveDrawerItemsData<LabelStyleType>(
+  childThreadInfosMap: { +[id: string]: $ReadOnlyArray<ThreadInfo> },
+  communities: $ReadOnlyArray<ResolvedThreadInfo>,
+  labelStyles: $ReadOnlyArray<LabelStyleType>,
+  maxDepth: number,
+): $ReadOnlyArray<CommunityDrawerItemData<LabelStyleType>> {
+  const result = communities.map(community => ({
+    threadInfo: community,
+    itemChildren: [],
+    labelStyle: labelStyles[0],
+    hasSubchannelsButton: false,
+  }));
+  let queue = result.map(item => [item, 0]);
+
+  for (let i = 0; i < queue.length; i++) {
+    const [item, lvl] = queue[i];
+    const itemChildThreadInfos = childThreadInfosMap[item.threadInfo.id] ?? [];
+
+    if (lvl < maxDepth) {
+      item.itemChildren = itemChildThreadInfos
+        .filter(childItem => communitySubthreads.includes(childItem.type))
+        .map(childItem => ({
+          threadInfo: childItem,
+          itemChildren: [],
+          labelStyle: labelStyles[Math.min(lvl + 1, labelStyles.length - 1)],
+          hasSubchannelsButton:
+            lvl + 1 === maxDepth &&
+            threadHasSubchannels(childItem, childThreadInfosMap),
+        }));
+      queue = queue.concat(
+        item.itemChildren.map(childItem => [childItem, lvl + 1]),
+      );
+    }
+  }
+  return result;
+}
+
+function threadHasSubchannels(
+  threadInfo: ThreadInfo,
+  childThreadInfosMap: { +[id: string]: $ReadOnlyArray<ThreadInfo> },
+): boolean {
+  if (!childThreadInfosMap[threadInfo.id]?.length) {
+    return false;
+  }
+  return childThreadInfosMap[threadInfo.id].some(thread =>
+    threadIsChannel(thread),
+  );
+}
+
+function appendSuffix(
+  chats: $ReadOnlyArray<ResolvedThreadInfo>,
+): ResolvedThreadInfo[] {
+  const result = [];
+  const names = new Map<string, number>();
+
+  for (const chat of chats) {
+    let name = chat.uiName;
+    const numberOfOccurrences = names.get(name);
+    names.set(name, (numberOfOccurrences ?? 0) + 1);
+    if (numberOfOccurrences) {
+      name = `${name} (${numberOfOccurrences.toString()})`;
+    }
+    result.push({ ...chat, uiName: name });
+  }
+  return result;
+}
+
+export { createRecursiveDrawerItemsData, appendSuffix };
diff --git a/native/navigation/community-drawer-content.react.js b/native/navigation/community-drawer-content.react.js
--- a/native/navigation/community-drawer-content.react.js
+++ b/native/navigation/community-drawer-content.react.js
@@ -9,18 +9,15 @@
   childThreadInfos,
   communityThreadSelector,
 } from 'lib/selectors/thread-selectors.js';
-import { threadIsChannel } from 'lib/shared/thread-utils.js';
 import {
-  type ThreadInfo,
-  type ResolvedThreadInfo,
-  communitySubthreads,
-} from 'lib/types/thread-types.js';
+  createRecursiveDrawerItemsData,
+  appendSuffix,
+} from 'lib/utils/drawer-utils.react.js';
 import { useResolvedThreadInfos } from 'lib/utils/entity-helpers.js';
 
 import CommunityDrawerItemCommunity from './community-drawer-item-community.react.js';
 import { useNavigateToThread } from '../chat/message-list-types.js';
 import { useStyles } from '../themes/colors.js';
-import type { TextStyle } from '../types/styles.js';
 
 const maxDepth = 2;
 const safeAreaEdges = Platform.select({
@@ -49,23 +46,15 @@
   }, []);
 
   const renderItem = React.useCallback(
-    ({ item }) => {
-      const itemData = {
-        threadInfo: item.threadInfo,
-        itemChildren: item.itemChildren,
-        labelStyle: item.labelStyle,
-        hasSubchannelsButton: item.subchannelsButton,
-      };
-      return (
-        <CommunityDrawerItemCommunity
-          key={item.key}
-          itemData={itemData}
-          toggleExpanded={setOpenCommunityOrClose}
-          expanded={itemData.threadInfo.id === openCommunity}
-          navigateToThread={navigateToThread}
-        />
-      );
-    },
+    ({ item }) => (
+      <CommunityDrawerItemCommunity
+        key={item.threadInfo.id}
+        itemData={item}
+        toggleExpanded={setOpenCommunityOrClose}
+        expanded={item.threadInfo.id === openCommunity}
+        navigateToThread={navigateToThread}
+      />
+    ),
     [navigateToThread, openCommunity, setOpenCommunityOrClose],
   );
 
@@ -85,6 +74,7 @@
         childThreadInfosMap,
         communitiesSuffixed,
         labelStyles,
+        maxDepth,
       ),
     [childThreadInfosMap, communitiesSuffixed, labelStyles],
   );
@@ -96,73 +86,6 @@
   );
 }
 
-function createRecursiveDrawerItemsData(
-  childThreadInfosMap: { +[id: string]: $ReadOnlyArray<ThreadInfo> },
-  communities: $ReadOnlyArray<ResolvedThreadInfo>,
-  labelStyles: $ReadOnlyArray<TextStyle>,
-) {
-  const result = communities.map(community => ({
-    key: community.id,
-    threadInfo: community,
-    itemChildren: [],
-    labelStyle: labelStyles[0],
-    subchannelsButton: false,
-  }));
-  let queue = result.map(item => [item, 0]);
-
-  for (let i = 0; i < queue.length; i++) {
-    const [item, lvl] = queue[i];
-    const itemChildThreadInfos = childThreadInfosMap[item.threadInfo.id] ?? [];
-
-    if (lvl < maxDepth) {
-      item.itemChildren = itemChildThreadInfos
-        .filter(childItem => communitySubthreads.includes(childItem.type))
-        .map(childItem => ({
-          threadInfo: childItem,
-          itemChildren: [],
-          labelStyle: labelStyles[Math.min(lvl + 1, labelStyles.length - 1)],
-          hasSubchannelsButton:
-            lvl + 1 === maxDepth &&
-            threadHasSubchannels(childItem, childThreadInfosMap),
-        }));
-      queue = queue.concat(
-        item.itemChildren.map(childItem => [childItem, lvl + 1]),
-      );
-    }
-  }
-  return result;
-}
-
-function threadHasSubchannels(
-  threadInfo: ThreadInfo,
-  childThreadInfosMap: { +[id: string]: $ReadOnlyArray<ThreadInfo> },
-) {
-  if (!childThreadInfosMap[threadInfo.id]?.length) {
-    return false;
-  }
-  return childThreadInfosMap[threadInfo.id].some(thread =>
-    threadIsChannel(thread),
-  );
-}
-
-function appendSuffix(
-  chats: $ReadOnlyArray<ResolvedThreadInfo>,
-): ResolvedThreadInfo[] {
-  const result = [];
-  const names = new Map<string, number>();
-
-  for (const chat of chats) {
-    let name = chat.uiName;
-    const numberOfOccurrences = names.get(name);
-    names.set(name, (numberOfOccurrences ?? 0) + 1);
-    if (numberOfOccurrences) {
-      name = `${name} (${numberOfOccurrences.toString()})`;
-    }
-    result.push({ ...chat, uiName: name });
-  }
-  return result;
-}
-
 const unboundStyles = {
   drawerContent: {
     flex: 1,
diff --git a/native/navigation/community-drawer-item.react.js b/native/navigation/community-drawer-item.react.js
--- a/native/navigation/community-drawer-item.react.js
+++ b/native/navigation/community-drawer-item.react.js
@@ -3,7 +3,7 @@
 import * as React from 'react';
 import { View, FlatList, TouchableOpacity } from 'react-native';
 
-import type { ThreadInfo } from 'lib/types/thread-types.js';
+import type { CommunityDrawerItemData } from 'lib/utils/drawer-utils.react.js';
 import { useResolvedThreadInfo } from 'lib/utils/entity-helpers.js';
 
 import { ExpandButton, ExpandButtonDisabled } from './expand-buttons.react.js';
@@ -13,15 +13,8 @@
 import { useStyles } from '../themes/colors.js';
 import type { TextStyle } from '../types/styles.js';
 
-export type CommunityDrawerItemData = {
-  +threadInfo: ThreadInfo,
-  +itemChildren?: $ReadOnlyArray<CommunityDrawerItemData>,
-  +labelStyle: TextStyle,
-  +hasSubchannelsButton: boolean,
-};
-
 export type DrawerItemProps = {
-  +itemData: CommunityDrawerItemData,
+  +itemData: CommunityDrawerItemData<TextStyle>,
   +toggleExpanded: (threadID: string) => void,
   +expanded: boolean,
   +navigateToThread: (params: MessageListParams) => void,
@@ -120,7 +113,7 @@
 };
 
 export type CommunityDrawerItemChatProps = {
-  +itemData: CommunityDrawerItemData,
+  +itemData: CommunityDrawerItemData<TextStyle>,
   +navigateToThread: (params: MessageListParams) => void,
 };