# How Zed Implements Remote Development and Pair Programming: A Deep Dive into the Collab Architecture

> Explore Zed's remote development and pair programming with Collab. Learn how this WebSocket RPC engine enables real-time collaboration, audio/video calls, and shared UI controls.

- Repository: [Zed Industries/zed](https://github.com/zed-industries/zed)
- Tags: deep-dive
- Published: 2026-03-01

---

**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`](https://github.com/zed-industries/zed/blob/main/crates/collab/src/rpc.rs)): Implements a binary RPC protocol built on top of `rpc::proto` that 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`](https://github.com/zed-industries/zed/blob/main/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`.

```rust
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 identity
- `connection_id`: A unique identifier per socket
- `db`: A transactional handle to the PostgreSQL-based collab database
- `peer`: A low-level `rpc::Connection` for sending and receiving `TypedEnvelope`s
- `connection_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.
- **`CallStarted`** and **`CallCanceled`**: 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`](https://github.com/zed-industries/zed/blob/main/buffer_operation.rs)) that can be deterministically replayed in sequence. The server tracks **observed edits** ([`observed_buffer_edits.rs`](https://github.com/zed-industries/zed/blob/main/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`](https://github.com/zed-industries/zed/blob/main/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`](https://github.com/zed-industries/zed/blob/main/crates/collab_ui/src/collab_ui.rs)), which registers workspace actions including:

- `ToggleFocus`: Opens or closes the Collab panel
- `ShareProject`: Initiates project sharing for remote development
- `ScreenShare`, `Mute`, `Deafen`: Controls audio/video state
- `LeaveCall`: 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** (`ListEntry` enum) representing active calls, channels, contacts, and invitations
- Subscriptions to `ChannelStore`, `UserStore`, and the global `ActiveCall` singleton 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`](https://github.com/zed-industries/zed/blob/main/crates/workspace/src/workspace.rs) line 7156).

### Sharing Projects for Remote Development

When a user triggers **"Share Project"** (action defined in [`collab_panel.rs`](https://github.com/zed-industries/zed/blob/main/collab_panel.rs) lines 51‑66), the following sequence enables remote development:

1. The UI invokes `ActiveCall::global(cx).update` → `call.share_project(project, cx)`.
2. The `share_project` handler in [`crates/collab/src/rpc.rs`](https://github.com/zed-industries/zed/blob/main/crates/collab/src/rpc.rs) stores the project root path in PostgreSQL and broadcasts a `ShareProject` RPC to room participants.
3. Remote clients receive the message and render a **Channel** entry; selecting it opens a **ChannelView** ([`crates/collab_ui/src/channel_view.rs`](https://github.com/zed-industries/zed/blob/main/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`](https://github.com/zed-industries/zed/blob/main/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`](https://github.com/zed-industries/zed/blob/main/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`](https://github.com/zed-industries/zed/blob/main/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`](https://github.com/zed-industries/zed/blob/main/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

```rust
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`](https://github.com/zed-industries/zed/blob/main/collab_panel.rs)) calls `ActiveCall::global(cx).update(|call, cx| call.share_project(project, cx))`.

### Joining a Remote Channel Invitation

```rust
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`](https://github.com/zed-industries/zed/blob/main/channel_view.rs)) creates a view bound to the shared channel and registers for `UpdateChannelBuffer` RPCs.

### Initiating Pair Programming with Screen Share

```rust
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`](https://github.com/zed-industries/zed/blob/main/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`](https://github.com/zed-industries/zed/blob/main/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`](https://github.com/zed-industries/zed/blob/main/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`](https://github.com/zed-industries/zed/blob/main/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`](https://github.com/zed-industries/zed/blob/main/crates/collab_ui/src/channel_view.rs)) applies remote edits immediately via `UpdateChannelBuffer` messages, 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`](https://github.com/zed-industries/zed/blob/main/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`](https://github.com/zed-industries/zed/blob/main/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`](https://github.com/zed-industries/zed/blob/main/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`](https://github.com/zed-industries/zed/blob/main/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.