diff --git a/web/sidebar/community-drawer-item-community.react.js b/web/sidebar/community-drawer-item-community.react.js
new file mode 100644
--- /dev/null
+++ b/web/sidebar/community-drawer-item-community.react.js
@@ -0,0 +1,25 @@
+// @flow
+
+import classnames from 'classnames';
+import * as React from 'react';
+
+import css from './community-drawer-item.css';
+import type { DrawerItemProps } from './community-drawer-item.react.js';
+import CommunityDrawerItem from './community-drawer-item.react.js';
+
+function CommunityDrawerItemCommunity(props: DrawerItemProps): React.Node {
+  const classes = classnames({
+    [css.communityBase]: true,
+    [css.communityExpanded]: props.expanded,
+  });
+  return (
+    <div className={classes}>
+      <CommunityDrawerItem {...props} />
+    </div>
+  );
+}
+
+const MemoizedCommunityDrawerItemCommunity: React.ComponentType<DrawerItemProps> = React.memo(
+  CommunityDrawerItemCommunity,
+);
+export default MemoizedCommunityDrawerItemCommunity;
diff --git a/web/sidebar/community-drawer-item.css b/web/sidebar/community-drawer-item.css
new file mode 100644
--- /dev/null
+++ b/web/sidebar/community-drawer-item.css
@@ -0,0 +1,66 @@
+.threadEntry {
+  display: flex;
+  flex-direction: row;
+  margin-top: 8px;
+  margin-bottom: 8px;
+}
+
+.threadListContainer {
+  display: flex;
+  flex-direction: column;
+}
+
+.titleWrapper {
+  overflow: hidden;
+}
+
+.title {
+  text-overflow: ellipsis;
+  white-space: nowrap;
+  overflow: hidden;
+  color: var(--drawer-item-color);
+  line-height: 24px;
+}
+
+.titleLevel0 {
+  font-size: var(--l-font-18);
+  font-weight: var(--semi-bold);
+}
+
+.titleLevel1,
+.titleLevel2 {
+  font-size: var(--m-font-16);
+  font-weight: var(--semi-bold);
+}
+
+.buttonContainer {
+  width: 24px;
+  align-items: center;
+  justify-content: center;
+  display: flex;
+}
+
+.chatItem {
+  margin-left: 16px;
+}
+
+.communityBase {
+  padding: 2px;
+  padding-right: 24px;
+  padding-left: 8px;
+  overflow: hidden;
+}
+
+.communityExpanded {
+  background-color: var(--drawer-open-community-bg);
+  border-top-right-radius: 8px;
+  border-bottom-right-radius: 8px;
+}
+
+.subchannelsButton {
+  margin-left: 24px;
+  margin-bottom: 6px;
+  margin-top: 4px;
+  display: flex;
+  align-items: center;
+}
diff --git a/web/sidebar/community-drawer-item.react.js b/web/sidebar/community-drawer-item.react.js
new file mode 100644
--- /dev/null
+++ b/web/sidebar/community-drawer-item.react.js
@@ -0,0 +1,135 @@
+// @flow
+
+import classnames from 'classnames';
+import * as React from 'react';
+
+import type { CommunityDrawerItemData } from 'lib/utils/drawer-utils.react.js';
+import { useResolvedThreadInfo } from 'lib/utils/entity-helpers.js';
+
+import css from './community-drawer-item.css';
+import { ExpandButton } from './expand-buttons.react.js';
+import SubchannelsButton from './subchannels-button.react.js';
+import { useSelector } from '../redux/redux-utils.js';
+import {
+  useOnClickThread,
+  useThreadIsActive,
+} from '../selectors/thread-selectors.js';
+
+export type DrawerItemProps = {
+  +itemData: CommunityDrawerItemData<string>,
+  +toggleExpanded: (threadID: string) => void,
+  +expanded: boolean,
+};
+
+function CommunityDrawerItem(props: DrawerItemProps): React.Node {
+  const {
+    itemData: { threadInfo, itemChildren, hasSubchannelsButton, labelStyle },
+    expanded,
+    toggleExpanded,
+  } = props;
+
+  const children = React.useMemo(() => {
+    if (!expanded) {
+      return null;
+    }
+    if (hasSubchannelsButton) {
+      return (
+        <div className={css.subchannelsButton}>
+          <SubchannelsButton threadInfo={threadInfo} />
+        </div>
+      );
+    }
+    if (!itemChildren) {
+      return null;
+    }
+    return itemChildren.map(item => (
+      <MemoizedCommunityDrawerItemChat
+        itemData={item}
+        key={item.threadInfo.id}
+      />
+    ));
+  }, [expanded, hasSubchannelsButton, itemChildren, threadInfo]);
+
+  const onExpandToggled = React.useCallback(
+    () => toggleExpanded(threadInfo.id),
+    [toggleExpanded, threadInfo.id],
+  );
+
+  const itemExpandButton = React.useMemo(() => {
+    if (itemChildren?.length === 0 && !hasSubchannelsButton) {
+      return (
+        <div className={css.buttonContainer}>
+          <ExpandButton disabled={true} />
+        </div>
+      );
+    }
+    return (
+      <div className={css.buttonContainer}>
+        <ExpandButton onClick={onExpandToggled} expanded={expanded} />
+      </div>
+    );
+  }, [itemChildren?.length, hasSubchannelsButton, onExpandToggled, expanded]);
+
+  const active = useThreadIsActive(threadInfo.id);
+  const isCreateMode = useSelector(
+    state => state.navInfo.chatMode === 'create',
+  );
+  const onClick = useOnClickThread(threadInfo);
+  const selectItemIfNotActiveCreation = React.useCallback(
+    (event: SyntheticEvent<HTMLAnchorElement>) => {
+      if (!isCreateMode || !active) {
+        onClick(event);
+      }
+    },
+    [isCreateMode, active, onClick],
+  );
+
+  const { uiName } = useResolvedThreadInfo(threadInfo);
+  const titleLabel = classnames(css.title, css[labelStyle]);
+
+  return (
+    <>
+      <div className={css.threadEntry}>
+        {itemExpandButton}
+        <a onClick={selectItemIfNotActiveCreation} className={css.titleWrapper}>
+          <div className={titleLabel}>{uiName}</div>
+        </a>
+      </div>
+      <div className={css.threadListContainer}>{children}</div>
+    </>
+  );
+}
+
+export type CommunityDrawerItemChatProps = {
+  +itemData: CommunityDrawerItemData<string>,
+};
+
+function CommunityDrawerItemChat(
+  props: CommunityDrawerItemChatProps,
+): React.Node {
+  const [expanded, setExpanded] = React.useState(false);
+
+  const toggleExpanded = React.useCallback(() => {
+    setExpanded(isExpanded => !isExpanded);
+  }, []);
+
+  return (
+    <div className={css.chatItem}>
+      <MemoizedCommunityDrawerItem
+        {...props}
+        expanded={expanded}
+        toggleExpanded={toggleExpanded}
+      />
+    </div>
+  );
+}
+
+const MemoizedCommunityDrawerItemChat: React.ComponentType<CommunityDrawerItemChatProps> = React.memo(
+  CommunityDrawerItemChat,
+);
+
+const MemoizedCommunityDrawerItem: React.ComponentType<DrawerItemProps> = React.memo(
+  CommunityDrawerItem,
+);
+
+export default MemoizedCommunityDrawerItem;
diff --git a/web/theme.css b/web/theme.css
--- a/web/theme.css
+++ b/web/theme.css
@@ -196,4 +196,6 @@
   --purple-link: var(--violet-light-100);
   --drawer-expand-button: var(--shades-black-60);
   --drawer-expand-button-disabled: var(--shades-black-80);
+  --drawer-item-color: var(--shades-white-60);
+  --drawer-open-community-bg: #191919;
 }