From group chats to structured communities
A single group chat works when an app has a few dozen users talking about one thing. It stops working the moment those users want to talk about several things at once. Announcements drown in chatter, new members cannot catch up, and moderators have no way to separate topics or control who can post.
That is the problem Discord solved with servers and channels, and it is why community-style messaging has become an expectation in gaming apps, creator platforms, fan apps, interest groups, and online education products. Users want a top-level home they join, and inside that home they want separate topic channels that each carry their own conversations.
ZIM, ZEGOCLOUD’s in-app chat SDK, added this model in ZIM 3.0.0 with the Community feature. This article explains how the ZIM community model is structured and walks through creating a community, adding channels, managing members, sending channel messages, and moderating with mute.
The ZIM community model
ZIM organizes large-group chat around a three-tier structure:
- Community — the top-level container that aggregates members and their relationships. Users must create or join a community before they can interact inside it. Think of it as a Discord server.
- Channel — the basic carrier of chat interaction inside a community. Every channel carries its own messages and conversation, just as a Discord channel does. Channels support text, image, voice, video, and other standard ZIM message types.
- Thread — a focused discussion expanded from a single channel message. The community/channel APIs are available now; the thread tier is planned for a future version.
Communities and channels are deliberately different from ZIM’s existing groups:
| Feature | Community | Group |
|---|---|---|
| Maximum members | 100,000 by default, expandable to unlimited | 2,000 (configurable) |
| Channels / sub-groups | Multiple channels inside one community | Not supported |
| Roles | Owner, admin, regular member | Owner, admin, regular member |
| Join method | Join actively or be invited | Invite, request, or search to join |
| Message model | Isolated per channel | One unified message stream |
| Best for | Large-scale, forum-style communities | Small-to-medium team collaboration |
A few default limits are worth knowing when you design the data model: a community holds 100 channels by default (expandable to 1,000), a user can join 100 communities by default (expandable to 500), and there is no limit on the number of communities under one AppID. Community names allow up to 300 characters, notices up to 500, and each community supports up to 10 custom attribute pairs.
Community is a premium capability included with the ZIM premium edition — it must be activated by ZEGOCLOUD technical support before the APIs will work, and the client SDK must be 3.0.0 or later. Token authentication for community calls is the same token mechanism used by every other ZIM feature, with no extra permission declarations.
How channels work inside a community
When a community is created, ZIM automatically creates a default GENERAL channel that every member joins automatically. Community-wide tips and notifications go there. Owners and admins can then create additional PUBLIC channels; members auto-join those as well. The two types behave identically — the only difference is creation timing — which keeps the model simple: one channel type for everything, distinguished by channel ID rather than visibility rules.
Two identifiers are easy to confuse and are called out explicitly in the docs:
channelIDidentifies a channel for management operations — creating, renaming, dismissing, or querying it.conversationID(available on theZIMCommunityChannelobject returned byqueryCommunityChannelList) is what you use to send and receive messages and to manage the channel conversation.
Use the wrong one and messages will not reach the channel.
The complete feature set is covered by seven guides: community management, community member management, and community mute on the community side; channel management, channel message management, and channel conversation management on the channel side, all anchored by the community overview. Dedicated guides are published for Android, iOS, macOS, Windows, and React Native, and the same API set is also documented for Web and Flutter.
Build it: communities and channels step by step
Prerequisites
Before any community call, complete the standard ZIM setup described in the send and receive messages guide: integrate the SDK, initialize ZIM, and log in with token-based authentication. Community operations are currently client-SDK only — there are no server-side management APIs, and community event notifications arrive through client callbacks.
1. Create a community
Call createCommunity with a ZIMCommunityInfo and an optional ZIMCommunityCreateConfig. The creator automatically becomes the community owner and is joined automatically, so there is no separate join call. A custom communityID accepts numbers, English characters, and a defined set of symbols; leave it blank and the server generates one with a #B prefix.
ZIMCommunityInfo communityInfo = new ZIMCommunityInfo();
communityInfo.setCommunityID("community_001");
communityInfo.setCommunityName("My Community"); // max 300 characters
communityInfo.setCommunityAvatarUrl("https://example.com/avatar.png");
ZIMCommunityCreateConfig config = new ZIMCommunityCreateConfig();
config.setCommunityNotice("Welcome!"); // max 500 characters
HashMap<String, String> attributes = new HashMap<>();
attributes.put("key1", "value1"); // up to 10 pairs
config.setCommunityAttributes(attributes);
zim.createCommunity(communityInfo, config, (fullInfo, error) -> {
if (error.code == ZIMErrorCode.SUCCESS) {
// Community created; the default GENERAL channel already exists
}
});
Other users join with joinCommunity (they automatically enter the default and public channels), leave with leaveCommunity, and the owner can dismiss the whole community with dismissCommunity, which also dismisses every channel inside it. Owners cannot leave without first transferring ownership or dismissing the community.
2. Add channels
Only the owner and admins can create channels. createCommunityChannel takes a ZIMCommunityChannelInfo and a ZIMCommunityChannelCreateConfig; the creator is joined automatically.
ZIMCommunityChannelInfo channelInfo = new ZIMCommunityChannelInfo();
channelInfo.setChannelID("channel_001");
channelInfo.setChannelName("Announcements");
channelInfo.setCommunityID(communityID);
ZIMCommunityChannelCreateConfig channelConfig = new ZIMCommunityChannelCreateConfig();
channelConfig.setChannelNotice("Read before posting");
zim.createCommunityChannel(channelInfo, channelConfig, (channelFullInfo, errorInfo) -> {
if (errorInfo.code == ZIMErrorCode.SUCCESS) {
// channelFullInfo.getConversationID() is the ID for messaging
}
});
The channel management APIs also cover renaming a channel, updating its avatar and notice, setting or deleting custom channel attributes, dismissing a channel (the default GENERAL channel cannot be dismissed), and querying channel info or the full channel list. Pagination uses a nextFlag cursor: start at 0, pass the returned flag into the next request, and stop when it comes back 0.
3. Invite and manage members
Membership is administered through the community member management APIs:
inviteUsersIntoCommunity— batch-invite up to 100 registered users per call. Invitations do not require consent; invited users become members directly.kickCommunityMembers— owner/admin only; removes up to 100 members per call.updateCommunityMemberRole— owner only; promotes or demotes between regular member (3), admin (2), and owner (1).transferCommunityOwner— owner only; the previous owner becomes a regular member.queryCommunityMemberList/queryCommunityMembers— paginated roster queries and batched lookups of role and mute state.
Two callbacks keep the UI in sync: onCommunityMemberStateChanged fires when members enter or leave, and onCommunityMemberInfoUpdated fires when role, nickname, or mute information changes.
4. Send and receive channel messages
Channel messaging reuses ZIM’s standard sendMessage API. The only difference from one-to-one or group chat is the conversation type: ZIMConversationType.COMMUNITY_CHANNEL, combined with the channel’s conversationID.
String conversationID = channel.getConversationID();
ZIMTextMessage textMessage = new ZIMTextMessage();
textMessage.setMessage("Hello, Channel!");
ZIMMessageSendConfig config = new ZIMMessageSendConfig();
config.setPriority(ZIMMessagePriority.LOW);
zim.sendMessage(textMessage, conversationID,
ZIMConversationType.COMMUNITY_CHANNEL, config, callback);
The same pattern applies to image, file, audio, video, custom, and combined messages — identical payloads to group messages, different conversationType. Note the client enforces a minimum interval of 100ms between two sends.
Since 3.0.0, all incoming online messages — one-to-one, group, room, and community channel — arrive through one unified onMessageReceived callback. Filter on receivedInfo.conversationType == COMMUNITY_CHANNEL, then dispatch by message type. History is pulled through the standard get-message-history API using the channel conversationID, and channels support the full advanced messaging toolkit: recall, edit, emoji reactions, tip messages, local message insertion, message extensions, and local search.
5. Moderate with mute
ZIM offers two complementary mute controls.
Channel-wide mute uses muteCommunityChannels with a ZIMCommunityChannelMuteConfig supporting four scopes: NONE, NORMAL (regular members only), ALL, and CUSTOM (a caller-specified role list). Duration runs from one second to roughly 30 days, or -1 for permanent mute. It works as a batch operation across multiple channels. Note that community mute currently operates on channels within a community; a community-level global mute is not yet supported.
Per-member mute uses muteCommunityMembers (owner/admin only). The config takes a duration and an optional channelID — set it to mute a user in one specific channel, or leave it blank to mute them across all channels.
On the conversation side, clearConversationUnreadMessageCount, setConversationDraft, and setConversationNotificationStatus (do-not-disturb) all work against the channel conversationID with the COMMUNITY_CHANNEL type, and the community itself has a notification status that controls whether channel unread counts roll up into the community total.
What this enables: two examples
A creator community with topic channels. A creator’s fans join one community and land in the default GENERAL channel for announcements. Admins create public channels for different topics — fan art, events, feedback — so each conversation stays isolated. New members auto-join every channel, the creator posts in GENERAL with an all-member mute to keep it announcement-only, and fan discussion continues unmuted in the topic channels.
A game guild with role-based channels. A guild runs as a community of up to 100,000 members. Guild leadership holds the owner and admin roles, ordinary players are regular members, and channels map to squads, tactics, and off-topic chat. Disruptive players can be muted in a single channel or everywhere, roles can be promoted when officers change, and ownership transfers cleanly when leadership changes hands — all without rebuilding the chat layer, and all on the same ZEGOCLOUD platform that already powers the game’s voice and video.
Key takeaways
- A community groups members; channels inside it carry isolated messages and conversations — the Discord server/channel pattern, native in ZIM 3.0.0.
- Communities scale to 100,000 members (expandable) versus 2,000 for groups, with up to 100 channels by default.
- Management is complete on the client: create/dismiss, join/leave, roles and ownership transfer, invites and removal, attributes, notices, and event callbacks.
- Messaging is the familiar
sendMessageflow withZIMConversationType.COMMUNITY_CHANNEL; just remember to useconversationID, notchannelID. - Moderation combines channel-wide mute (by role scope) with per-member mute (per channel or community-wide).
- Because ZIM runs on the ZEGOCLOUD platform, chat sits alongside voice, video, and live streaming from one vendor — no second chat provider to stitch into the same real-time stack.
FAQ
What is the difference between a community and a channel in ZIM?
A community is the top-level container that groups members; channels live inside a community and carry the actual messages and conversations. This mirrors how Discord servers hold channels. A community also provides member management, roles, and notice settings, while each channel maintains its own isolated message stream and conversation state.
Which platforms support ZIM communities and channels?
The community and channel guides ship for Android, iOS, macOS, Windows, and React Native as of ZIM 3.0.0, and the same API set is also documented for Web and Flutter. All platforms require ZIM SDK 3.0.0 or later.
Can I moderate a community?
Yes. ZIM provides community member management — invites, removal, role changes, and ownership transfer — plus community mute. Channel mute can target regular members, all members, or a custom set of roles for a fixed duration or permanently, and individual members can be muted in one channel or across the whole community.
Do I need a separate SDK for voice or video in my community?
No. ZIM communities run on the same ZEGOCLOUD platform as voice, video, and live streaming. One vendor and one real-time stack cover community chat and real-time media, so teams do not have to integrate and maintain a separate chat provider alongside their voice and video SDK.
Keep building
Ready to add structured community chat to your product? Explore the In-app Chat product page and start with the ZIM community overview in the developer docs, where every community and channel API in this article is documented with code for each supported platform.
Let’s Build APP Together
Start building with real-time video, voice & chat SDK for apps today!






