Hey 👋, Aman here. This is a summary of all the work I did for the Zulip chat application and my personal experiences as a part of the Google Summer of Code 2025.
What is Zulip?
Zulip is an open-source group chat application built to make conversations both organized and easy to follow. While most chat tools pile everything into one fast-moving feed, Zulip takes a different approach with its topic-based threading system.
-
Streams and Topics: In Zulip, discussions are arranged within streams (similar to channels), and every message belongs to a specific topic. This structure ensures that conversations stay on track and users can quickly revisit any thread without sifting through unrelated messages.
-
Best of Both Worlds: Zulip is designed to handle both real-time conversations and asynchronous communication seamlessly. Whether a team is working together live or catching up later from different time zones, Zulip makes it easy to stay in sync.
-
Open Source with a Strong Community: As a fully open-source project, Zulip is shaped and improved by a global community of contributors. It’s widely adopted across industries—from startups and open-source projects to research institutions and large organizations.
-
Feature-Rich Collaboration Hub: Beyond messaging, Zulip offers powerful integrations, advanced search, markdown support, bots, and many other features that make it more than just a chat app—it’s a central place for collaboration.
Why Zulip? - Efficient communication with organized team chat.
- Title : Cluster of Priority Features focused around message feed and editing.
- Repository: zulip/zulip
- Mentors: Afeefuddin & Sanchit Sharma
- Project Size: Large
- Checkins: Aman (whilstsomeody)
- Commits during GSoC
- Pull requests merged during GSoC
- All commits in zulip/zulip
- All merged pull requests
Let's dive deeper into the work I did with the amazing Zulip community.
- UI/UX improvements
I worked on standardizing the casing of language names in dropdowns, such as in the auto-complete menu in Settings → Code playgrounds, to ensure consistency with typeahead behavior in code blocks. I also fixed issues related to displaying the move messages count, making sure it appears correctly across different views. Additionally, I improved cursor and focus handling in the settings menus and custom forms to make the interface more intuitive for users.
- Message and unread marker handling
I fixed bugs related to unread and move message counts in certain narrows, ensuring that the displayed counts are accurate. I also implemented logic to automatically remove unread markers for messages when a stream is archived, which eliminates the need for users to manually mark them as read. Furthermore, I worked on marking muted topic messages as read, improving consistency in how unread behavior is handled across different contexts.
- Invites and permissions
I implemented support for editing multi-use invites, allowing users to update the invites they created. Admins were also given the ability to edit invites created by lower-role members. These edits include changing the role of the invitee, updating the channels the new users will be joined to, and setting new welcome bot messages at any point in time.
- Keyboard shortcuts & platform-specific behavior
I refined the handling of keyboard shortcuts, specifically by special-casing the behavior of Ctrl + [ on macOS so that it remains consistent with its behavior on other operating systems. This ensures a uniform user experience across different platforms.
- Message actions and features
I added a new “Quote and reply” icon to the message action bar, with logic that ensures the icon is visible only when the corresponding menu option is hidden, and vice versa. I also worked on improving the delete-message workflow by introducing a clearer choice between “Delete for me” and “Delete for everyone,” making the process more convenient for users.
- Backend and database migrations
I contributed to backend changes and database migrations, including work to clear unread markers for messages in archived streams. I also fixed issues with subscription and unsubscription event handling during archival, ensuring that related events and counts are updated accurately.
-
#34016: Make it possible to unarchive a channel. (Bonding Period)
Previously, Zulip did not have the feature to unarchive a channel through the UI, so users had to contact support if a channel was archived, whether intentionally or unintentionally. This PR implements the feature that allows users to easily archive or unarchive channels at any time, without any loss.
Commits:
94077c9: settings: Do not hide "Generate email address" button when archiving.
0c4c78a: stream_data: Cleanup in 'mark_archived' function.
2780360: unarchive: Add support for unarchiving archived channels.
5c33cc9: streams: Improve formatting of channel archive/unarchive notifications.
012986c: deactivate_modal: Update message in modal to indicate reversibility.
a4e7621: stream_edit: Add loader to reactivate and deactivate stream modals
Discussions:
- https://chat.zulip.org/#narrow/channel/378-api-design/topic/archived.20streams
- https://chat.zulip.org/#narrow/channel/101-design/topic/.E2.9C.94.20unarchive.20channel
-
#34795: left_sidebar: Show sidebar menu icon for muted unread messages.
It was reported that there was no option to mark messages as read when only unread messages in muted streams and topics remained. This occurred because the logic for showing or hiding the sidebar menu icon relied solely on the home view count, which excludes unread messages in muted streams and topics. This PR fixes the issue by including unread messages in muted streams and topics when determining whether to show or hide the sidebar menu icon.
Commits:
21cf1df: left_sidebar: Show sidebar menu icon for muted unread messages.
Discussions:
-
#34545: message_delete: Refactor do_delete_messages to group messages by topic.
This PR is a refactor updating do_delete_messages to categorize messages by recipient and topic using a defaultdict. Messages are grouped into batches where each batch corresponds to a unique recipient and topic combination. For each group, a separate delete event is created and processed, ensuring compliance with API requirements that mandate one event per topic.
Commits:
b19368e: message_delete: Refactor do_delete_messages to group messages by topic.
08f03d9: message_delete: Avoid fetching Stream objects in loops.
e796ae1: test_message_delete: Add test for do_delete_messages grouping logic.
Discussions:
-
#33903: Hide topic resolved banner when channel picker is open.
It was reported that when forwarding messages, the channel picker and the topic-resolved banner were displayed simultaneously, with the channel picker overlapping the banner. This caused part of the banner to be hidden and looked visually inconsistent. This PR fixes the issue by ensuring the banner is displayed only when the channel picker is not open.
Commit:
44efb77: compose: Prevent displaying banner when channel picker is opened.
Discussions:
-
#33749: todo_widget: Disable "Add task" button when a task cannot be added.
This PR prevents users from adding either a duplicate or an empty task to the to-do list by disabling the “Add task” button in both cases. When the task name is missing, the button is disabled with a tooltip saying “Name the task before adding.” Similarly, instead of only showing a warning for duplicate task names, the button is now disabled with a tooltip saying “Cannot add duplicate task.”
Commits:
1024272: todo_widget: Disable "Add task" button when a task cannot be added.
Discussions:
-
#34918: Clean up placeholder text when no search results are found .
This PR corrects the placeholder tests in empty search banner when no results are found.
Commits:
9b787fc: narrow-banner: Add constant for empty "No search results" title.
ad4732a: narrow-banner: Use shared function for empty narrows with search data.
77cf174: empty_feed_notice: Show only query words for empty search results.
Discussions:
-
#33005: Correctly align the bot icon in message area.
It was observed that the bot icon in the message area appeared misaligned with the bot name, positioning slightly lower. This PR fixes the UI bug by correctly aligning the bot icon with the bot name.
Commits:
28b91c3: message_row: Correctly align bot icon in message area.
Discussions:
-
#32102: modal: Add options for which messages are mark as read.
This PR updates the mark messages as read modal to categorize messages before marking them as read. The modal now has three options — Muted topics, Topics you don’t follow, and All messages — allowing users to select one of these options to mark as read.
Commits:
b440e0d: modal: Add options for marking messages as read.
Discussions:
- https://chat.zulip.org/#narrow/stream/137-feedback/topic/coming.20back.20to.20lots.20of.20unreads/near/1792194
- https://chat.zulip.org/#narrow/channel/378-api-design/topic/mark.20muted-topic.20messages.20as.20read
-
#35290: Remove and update classes.
This PR updated various classes in the codebase from
nake casetobab caseand removes some unnecessary classes as well.Commits:
aa06b22: settings_user_list_row: Remove redundant classes.
204ae1f: admin_human_form: Update classes to kebab-case.
Discussions:
-
#35218: user_status_ui: Show remove status icon when only emoji is present.
Previously, due to a logic issue, the clear status icon did not appear when only an emoji was selected in the status—it appeared only when status text was present. This PR fixes the bug so that the clear status icon now disappears only when neither status text nor an emoji is present.
Commits:
69c6b90: user_status_ui: Show remove status icon when only emoji is present.
Discussions:
-
#35575: inbox_ui: Clarify inbox state when all sections are collapsed.
It was reported that the UI felt confusing when there was only a collapsed folder in the inbox view. To address this, this PR makes two improvements. First, it adds a note below the folders that says “All of your unread conversations are hidden. Click on a section, folder, or channel to see what’s inside.” This note is displayed in two situations: when all folders are collapsed, or when some folders are expanded but all visible channels are collapsed. Second, it introduces a “Show all” button that allows users to expand all collapsed folders at once.
Commits:
d0207a4: inbox_ui: Clarify inbox state when all sections are collapsed.
Discussions:
-
#35391: Allow managing your own profile from profile modal
This PR updates the profile modal by making the “Edit profile” button for your own profile open the “Manage user” tab, which is labeled as “Edit profile” in this case. It also unifies the redundant classes
.user-profile-manage-own-edit-buttonand.user-profile-manage-other-edit-buttoninto a single.user-profile-manage-edit-buttonclass, since both now perform the same task of routing to the “Manage user” tab. Additionally, it disables auto-save for the birthdate input in “Edit profile”.Commits:
aaa2336b: custom_profile_fields: Refactor code for handling date type fields. ec8318a: user_profile: Show manage profile tab for admin's own profile. e2d0d15: user-profile: Update header edit icon for admin's own profile. 12850cc: user_profile: Use "Edit profile" label for user's own profile. dad1f85: user-profile: Rename class for edit pencil buttons. 0bc99dc: user_profile: Disable role dropdown for only owner. 986cb6c: user-profile: Redirect to profile panel when admin becomes non-admin. fd9652f: settings: Live update role text in "Profile" panel.
Discussions:
- https://chat.zulip.org/#narrow/channel/138-user-questions/topic/ownership.20transfer.20issue
- https://chat.zulip.org/#narrow/channel/6-frontend/topic/Ownership.20transfer.20issue
-
#32824: Show splash screen for drag and drop action.
With this PR, we now show splash screen when the user drags and drops a file.
Commits:
df169f8: upload: Show drop anywhere overlay when user drags an upload file.
Discussions:
-
#34905: test_subs: Fix the incorrect syntax in 'test_unarchive_stream'.
This PR fixes a syntax mistake spotted here by replacing /json/streams/... with the correct /api/v1/streams/... and also removes the unnecessary login_user call when using api_patch.
Commits:
8ee1652: test_subs: Fix the incorrect syntax in 'test_unarchive_stream'.
Discussions:
-
#34907: test_subs: Fix syntax errors in tests.
This PR fixes the use of /json/... by replacing it with the correct /api/v1/.... Also removes unnecessary login_user call when using api_patch.
Commits:
89d04eb: test_subs: Fix syntax errors in tests.
-
#34950: message_delete: Fix flaky 'do_delete_messages' function.\
This commit fixes a flake in
do_delete_messages, because of whichtest_do_delete_messages_grouping_logictest occasionally failed due to nondeterministic ordering of "delete_message" events.Commits:
40ef097: message_delete: Fix flaky 'do_delete_messages' function.
Discussions:
-
#34799: Add "channels:archived" search filter.
This PR adds a channels:archived filter to make it possible to search only in archived channels, or only in non-archived channels by negating it. (The naming is analogous to channels:public).
Discussions:
-
#33561: Add option for marking a user as spammer in "Deactivate user" popover
This PR introduces a new feature that allows organization admins to mark other users as spammers when required. To do this, admins can go to the Deactivate user tab in a user’s profile and select whether they want to mark the user as a spammer. If selected, they are given the option to delete the user’s messages. When this option is chosen, the user’s messages are deleted, their name is updated to “Deleted user”, and their profile picture is removed.
Discussions:
- https://chat.zulip.org/#narrow/channel/101-design/topic/Add.20option.20to.20mark.20user.20as.20a.20spammer.2E
- https://chat.zulip.org/#narrow/channel/378-api-design/topic/Marking.20a.20user.20as.20spammer
- https://chat.zulip.org/#narrow/channel/3-backend/topic/Marking.20a.20user.20as.20spammer/with/2235115
-
#32892: Fix buggy move messages count problem.
PR 32155 introduced a bug that caused the move messages count to display incorrectly for certain views. This PR fixes the issue to ensure the count is shown correctly.
Discussions:
-
#32830: multiuse-invites: Add edit feature for multiuse invites
This PR introduces a feature that allows organization members to edit the multi-use invites they have created, while admins can also edit invites created by members with lower roles. Users can update the invitee’s role, modify the channels that new users will be added to, and set new welcome bot messages at any time.
Discussions:
- https://chat.zulip.org/#narrow/channel/101-design/topic/edit.20multiuse.20invites
- https://chat.zulip.org/#narrow/channel/378-api-design/topic/edit.20multiuse.20invites
-
#33304: Don't track unreads in archived channels
Previously, messages that were unread at the time of stream archiving remained marked as unread indefinitely, requiring users to manually mark them as read. This PR fixes the issue by automatically removing unread markers for messages when the stream they belong to is archived.
Discussions:
-
#34861: Add option for users to change their own role.
Previously, users who were permitted to change their own role had no way to do so, as there was no setting available for this functionality. This PR adds a setting in users’ personal settings that allows them to change their role easily, if permitted.
Discussions:
-
#35363: realm_playground: Use lowercase language names in dropdown.
This PR updates the language names in the auto-complete dropdown in Settings > Code playgrounds to use lowercase instead of the previously used uppercase format, ensuring consistency with the typeahead behavior in code blocks.
Discussions:
As Google Summer of Code comes to an end, I can’t help but reflect on my one-year journey with Zulip. When I started, I was a beginner, unsure and a little afraid to dive into something so big. Fast-forward to today, I realize how much I have grown—not just as a developer, but as a person. Zulip has been at the heart of this journey, and I will always remain grateful for the welcoming community, the excellent documentation, and the incredible support from mentors and contributors.
Over this period, I learned far more than I ever expected. From writing industry-level code, crafting clear commit messages, and using git rebase to keep pull requests clean, to understanding the code review process and learning the true value of collaboration, Zulip has shaped me in ways no textbook could. I also gained confidence in Git and GitHub, skills that once felt intimidating but now feel natural. Perhaps most importantly, I learned how to review my own work critically, address feedback thoughtfully, and communicate effectively within a global developer community.
I am deeply thankful to my mentors— Sanchit Sharma, Afeefuddin —for their patience, guidance, and invaluable feedback throughout the journey and my buddy Apoorva Pendse. I also want to thank Tim Abbott for helping me prioritize work and all the maintainers especially Sahil Batra providing insightful reviews, as well as Alya Abbott, Karl Stolley and Lauryn Menard for their continuous encouragement and support.
This experience has been nothing short of transformative. GSoC with Zulip was not just about code—it was about growth, confidence, and the joy of being part of a community building something real and impactful. Thank you, Zulip, for making this summer one of the most memorable chapters of my life. 💙

Hello sir and mentors,
My name is Azad Kumar, And I recently pursuing Bachelor's Degree in Computer Scince from Madhya Pradesh
MERN Stack
Java
Python
SQL
Blockchain
System Design (LLD & HLD)
Linux OS
Gen al
Backend development
Data structures & alogrithms
I am interested in contributing to the a highly scalable project is one that GSoC 2026
I have reviewed the project description and would like to begin contributing and understanding the expected the expected
deliverables.
Could you please guide me on:
where is the development repo/codebase for this project maintained?
Beginner-friendly tasks or areas I should explore first?
Are there any specific tools, datasets, or technologies I should set up before I start?
Looking forward to contributing meaningfully.
Thank you!
Azad kumar