How Zed Implements Remote Development and Pair Programming: A Deep Dive into the Collab Architecture
Zed implements remote development and pair programming through a WebSocket-based RPC engine called Collab that synchronizes buffer operations in real-time, manages LiveKit audio/video calls, and exposes collaborative UI controls through the collab_ui crate.
Zed, the high-performance code editor from zed-industries/zed, delivers a seamless remote development and pair programming experience through a sophisticated multi-layered architecture. The system combines a Rust-powered collaboration server with a responsive client UI to enable real-time code sharing, cursor following, and integrated voice/video communication. This implementation allows multiple developers to edit the same codebase simultaneously while maintaining low-latency synchronization and conflict resolution.
Architecture Overview
The Collab subsystem consists of three distinct layers that communicate over a secure WebSocket RPC channel:
- Server Layer (
crates/collab/src/): Manages rooms, participants, buffer synchronization, call signaling, screen sharing, and audio processing through an Axum-based HTTP server. - Protocol Layer (
crates/collab/src/rpc.rs): Implements a binary RPC protocol built on top ofrpc::protothat handles message envelopes, request/response pairing, and typed message routing. - Client UI Layer (
crates/collab_ui/src/): Provides UI components for "Share Project", "Join Call", "Follow Participant", and screen sharing functionality that integrate directly into the workspace.
Server-Side Collaboration Engine
WebSocket Connection Handling
The Collab binary in crates/collab/src/main.rs initializes an Axum HTTP server that upgrades /rpc requests to persistent WebSocket connections. The handle_websocket_request function (lines 96‑136) validates protocol versions, extracts the client’s Zed version, acquires a ConnectionGuard to enforce concurrent connection limits, and hands the socket to Server::handle_connection.
fn routes(server: Arc<Server>) -> Router<(), Body> {
Router::new()
.route("/rpc", get(handle_websocket_request)) // WebSocket entry point
.layer(...)
}
Session Management
Server::handle_connection (lines 335‑460) creates a Session struct that bundles critical connection state:
principal: The authenticated user identityconnection_id: A unique identifier per socketdb: A transactional handle to the PostgreSQL-based collab databasepeer: A low-levelrpc::Connectionfor sending and receivingTypedEnvelopesconnection_pool: A shared pool of active connections for broadcasting messages
The session spawns a foreground executor that guarantees all state updates occur on the UI thread, eliminating race conditions during concurrent edits.
Core RPC Messages
The rpc::proto module defines the message protocol used for remote development and pair programming. Key messages include:
ShareProject: Advertises a local file system root for sharing with room participants.UpdateChannelBuffer: Transmits buffer diffs (insert/delete operations) to synchronize text edits across clients.UpdateChannelBufferCollaborators: Notifies peers about participant additions, removals, and cursor positions.CallStartedandCallCanceled: Signal the creation or termination of LiveKit voice/video rooms.
Handlers for these messages are registered in Server::new (lines 78‑115), where share_project stores shared project metadata in the database and broadcasts availability to room members.
Persistence and Conflict Resolution
All collaborative state persists in the Collab database (crates/collab/src/db/*.rs). Buffer edits are stored as operations (buffer_operation.rs) that can be deterministically replayed in sequence. The server tracks observed edits (observed_buffer_edits.rs) to prevent redundant diff transmission to clients that already possess specific revisions, optimizing bandwidth for remote development scenarios.
LiveKit Integration for Audio/Video
When livekit_* configuration fields are present (crates/collab/src/lib.rs lines 23‑30), the server constructs a LiveKitClient (lines 34‑38) to mediate voice and video calls. The server forwards signaling messages between Zed clients and LiveKit rooms, enabling low-latency audio/video streams without handling media transport directly.
Client-Side UI and Workflow
UI Bootstrap and Action Registration
The collaboration UI initializes via collab_ui::init (lines 20‑26 in crates/collab_ui/src/collab_ui.rs), which registers workspace actions including:
ToggleFocus: Opens or closes the Collab panelShareProject: Initiates project sharing for remote developmentScreenShare,Mute,Deafen: Controls audio/video stateLeaveCall: Disconnects from active collaboration sessions
The Collab Panel Interface
CollabPanel::new (lines 302‑380) constructs the primary collaboration interface containing:
- A filter editor for searching channels and contacts
- A dynamic list of entries (
ListEntryenum) representing active calls, channels, contacts, and invitations - Subscriptions to
ChannelStore,UserStore, and the globalActiveCallsingleton for real-time state synchronization
The update_entries method (lines 998‑1261) renders participant lists with role indicators (guest, talker, member) and displays shared projects as ParticipantProject entries that local users can open via join_in_room_project (crates/workspace/src/workspace.rs line 7156).
Sharing Projects for Remote Development
When a user triggers "Share Project" (action defined in collab_panel.rs lines 51‑66), the following sequence enables remote development:
- The UI invokes
ActiveCall::global(cx).update→call.share_project(project, cx). - The
share_projecthandler incrates/collab/src/rpc.rsstores the project root path in PostgreSQL and broadcasts aShareProjectRPC to room participants. - Remote clients receive the message and render a Channel entry; selecting it opens a ChannelView (
crates/collab_ui/src/channel_view.rs) displaying shared buffers.
This workflow allows multiple developers to open, edit, and observe live updates of identical files across distributed environments.
Real-Time Pair Programming Features
Zed enables pair programming through synchronized editing and communication tools:
| Feature | Implementation Details |
|---|---|
| Start a call | CollabPanel registers ScreenShare and Mute actions. Clicking the phone icon triggers ActiveCall::global(cx).update to create a LiveKit room and broadcast CallStarted (handler in rpc.rs). |
| Join a call | Remote participants receive CallStarted → ActiveCall::global instantiates a local Call entity, displaying avatars in the status bar (title_bar::collab). |
| Follow participant | Clicking an avatar triggers Workspace::follow (crates/workspace/src/workspace.rs line 4962), synchronizing the local viewport with the remote user's cursor position and scroll state. |
| Screen sharing | The ScreenShare action invokes room.share_screen(source, cx) (crates/collab/src/rpc.rs lines 169‑183). The server forwards the stream via LiveKit; recipients view shared screens through workspace::open_shared_screen. |
| Live buffer sync | Local edits generate buffer operations (collab/src/buffer_operation.rs). Clients transmit UpdateChannelBuffer messages; the server propagates these to all participants, who apply updates via ChannelView::apply_update. |
Working with the Collaboration API
You can interact with Zed's remote development and pair programming features programmatically through the Collab UI crate:
Sharing the Current Workspace Programmatically
use collab_ui::collab_panel::CollabPanel;
use workspace::Workspace;
use gpui::{AppContext, Entity};
/// Triggers project sharing via the Collab panel.
pub fn share_current_project(workspace: &mut Workspace, cx: &mut AppContext) {
// Sends a `ShareProject` RPC to all room participants.
CollabPanel::share_project(workspace, cx);
}
Implementation reference: CollabPanel::share_project (lines 51‑66 in collab_panel.rs) calls ActiveCall::global(cx).update(|call, cx| call.share_project(project, cx)).
Joining a Remote Channel Invitation
use collab_ui::channel_view::ChannelView;
use workspace::Workspace;
use gpui::{AsyncWindowContext, Entity};
pub async fn join_remote_channel(
channel_id: ChannelId,
workspace: WeakEntity<Workspace>,
mut cx: AsyncWindowContext,
) -> anyhow::Result<()> {
// Opens the channel view and subscribes to buffer updates.
ChannelView::open(channel_id, None, workspace, cx.window_handle(), &mut cx).await?;
Ok(())
}
Implementation reference: ChannelView::open (lines 14‑31 in channel_view.rs) creates a view bound to the shared channel and registers for UpdateChannelBuffer RPCs.
Initiating Pair Programming with Screen Share
use collab_ui::collab_panel::CollabPanel;
use workspace::Workspace;
use gpui::AppContext;
/// Starts a voice/video call and immediately shares the screen.
pub fn start_pair_programming(workspace: &mut Workspace, cx: &mut AppContext) {
// Creates a LiveKit room.
CollabPanel::start_call(workspace, cx);
// Shares the primary display.
CollabPanel::share_screen(workspace, cx);
}
Implementation reference: CollabPanel::start_call (action call, lines 86‑88) creates a LiveKit room; CollabPanel::share_screen (action ScreenShare, lines 167‑176) calls ActiveCall::global(cx).update(|call, cx| call.share_screen(...)).
Summary
- WebSocket RPC Foundation: The Collab server (
crates/collab/src/main.rs) uses Axum to manage persistent WebSocket connections that handle all remote development and pair programming signaling. - Operation-Based Synchronization: Buffer edits are stored as replayable operations in PostgreSQL (
buffer_operation.rs), enabling deterministic conflict resolution across distributed clients. - LiveKit Media Integration: Audio and video calls are mediated through LiveKit (
crates/collab/src/lib.rs), with Zed handling signaling while delegating media transport to the LiveKit infrastructure. - Unified UI Controls: The
CollabPanel(crates/collab_ui/src/collab_panel.rs) provides a centralized interface for project sharing, call management, and participant following within the Zed workspace. - Real-Time Buffer Sync: The
ChannelView(crates/collab_ui/src/channel_view.rs) applies remote edits immediately viaUpdateChannelBuffermessages, maintaining sub-second latency for collaborative editing.
Frequently Asked Questions
How does Zed synchronize code changes between multiple users?
Zed synchronizes code changes through buffer operations stored in PostgreSQL. When a user edits a file, the client generates an operation representing the insert or delete action and sends an UpdateChannelBuffer RPC message to the Collab server. The server stores this operation in buffer_operation.rs and forwards it to all connected participants, who apply the change locally via ChannelView::apply_update. This operation-based approach ensures deterministic ordering and conflict resolution without requiring Operational Transformation (OT) complexity.
What protocol does Zed use for real-time collaboration?
Zed uses a binary RPC protocol built on WebSockets, defined in crates/collab/src/rpc.rs and generated from proto.proto. The protocol wraps typed messages in TypedEnvelope structures that support request/response correlation and broadcast messaging. This runs over a secure WebSocket connection upgraded from the /rpc endpoint in the Axum server (crates/collab/src/main.rs), providing low-latency bidirectional communication essential for real-time pair programming.
How does Zed handle audio and video in pair programming sessions?
Zed integrates with LiveKit for audio and video transport. When a user starts a call, the ActiveCall entity creates a LiveKit room and sends a CallStarted RPC through the Collab server. The server forwards signaling messages between clients and the LiveKit infrastructure (crates/collab/src/lib.rs lines 34‑38). Media streams never pass through Zed's server; instead, clients connect directly to LiveKit for low-latency WebRTC audio, video, and screen sharing, while Zed manages the signaling layer and UI state synchronization.
Can extensions access Zed's collaboration features programmatically?
Yes, extensions and internal code can access collaboration features through the collab_ui crate's public API. Functions like CollabPanel::share_project, CollabPanel::start_call, and ChannelView::open allow programmatic initiation of remote development and pair programming workflows. These methods interact with the global ActiveCall singleton and the RPC layer to send ShareProject, CallStarted, and related messages to the Collab server, enabling automated workspace sharing and call management from within Zed extensions.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →