← Back to DevBytes

Zed Remote Development: Complete Guide

Introduction to Zed Remote Development

Zed is a high-performance, multiplayer code editor built in Rust by the creators of Atom. One of its most powerful features is Remote Development, which allows you to run the Zed editor interface locally while executing your code, file operations, and language servers on a remote machine. This architecture gives you the speed of a native app combined with the flexibility of working on distant infrastructure.

Whether you're developing on a beefy cloud workstation, a company-secured bastion host, or a Raspberry Pi cluster in your closet, Zed's remote development capabilities let you edit code as if it lived on your local machine — without the latency of traditional SSH-based editors or the overhead of browser-based IDEs.

What Is Zed Remote Development?

Zed Remote Development is a client-server architecture where the Zed UI runs locally (the client) while a lightweight remote server process handles file system access, language server management, terminal sessions, and project indexing on the remote host. The two communicate over an encrypted SSH tunnel.

Unlike traditional remote editing approaches that mount directories over SSHFS or SFTP, Zed ships a dedicated binary to the remote host. This binary performs all the heavy lifting — syntax highlighting preprocessing, project-wide search indexing, and LSP orchestration — directly on the remote machine. Only the rendered UI state and user input travel across the network, keeping bandwidth usage minimal and responsiveness high.

Key Components

Why Remote Development Matters

Modern development workflows increasingly depend on resources that don't live on your laptop. Here's why remote development in Zed is a meaningful capability for developers and teams:

Performance on Large Codebases

If your project contains millions of lines of code, gigabytes of dependencies, or heavy build artifacts, indexing and language server operations can overwhelm a laptop. Running these tasks on a remote machine with more CPU, RAM, and fast NVMe storage dramatically improves editor responsiveness.

Consistent Environments

Team members can develop against an identical environment — same OS, same toolchain versions, same database access — eliminating the "works on my machine" problem. Onboarding new developers becomes a matter of granting SSH access rather than walking them through a lengthy local setup.

Secure Access to Sensitive Infrastructure

Many organizations restrict source code and production-adjacent data to internal networks. With remote development, your code never leaves the secured host. The local machine only ever sees the portions of files you actively open, reducing the risk of data leakage from a lost or compromised laptop.

Resource-Intensive Workloads

Machine learning, data engineering, and game development often require GPUs or large amounts of memory. Remote development lets you write and iterate on code on the same machine that runs it, eliminating the edit-compile-test round trip over a slow network mount.

Prerequisites and Setup

Before you begin, ensure you have the following in place:

Configuring SSH

Zed relies on your existing SSH configuration. A well-structured ~/.ssh/config file makes connecting to remote hosts seamless. Here's an example configuration:

# ~/.ssh/config

Host dev-server
    HostName 10.0.0.42
    User developer
    IdentityFile ~/.ssh/id_ed25519
    Port 22
    ServerAliveInterval 60
    ServerAliveCountMax 3
    ControlMaster auto
    ControlPath ~/.ssh/cm-%r@%h:%p
    ControlPersist 10m

Host gpu-box
    HostName gpu.example.com
    User ml-engineer
    IdentityFile ~/.ssh/id_ed25519
    ForwardAgent yes
    LocalForward 6006 localhost:6006

The ControlMaster and ControlPersist directives are particularly valuable — they keep a persistent SSH connection open, reducing the latency of subsequent Zed operations that require new channels.

Verifying Connectivity

Before launching Zed, confirm that SSH works without interactive prompts:

ssh dev-server "echo 'Connection successful' && uname -a"

If you see output without being prompted for a password or passphrase, you're ready to proceed. If not, resolve SSH authentication first — Zed cannot bypass SSH prompts reliably.

Connecting to a Remote Project

There are two primary ways to open a remote project in Zed: through the UI or via the command line.

Method 1: Using the Command Palette

Follow these steps to connect through the Zed interface:

Method 2: Using the CLI

Zed's command-line interface supports opening remote projects directly. This is useful for scripting or quick access from a terminal:

# Open a remote project using an SSH host alias
zed ssh dev-server -- /home/developer/my-project

# Open with an inline SSH connection string
zed ssh developer@10.0.0.42 -- /home/developer/my-project

# Open a specific file in a remote project
zed ssh dev-server -- /home/developer/my-project/src/main.rs

The -- separator distinguishes SSH connection arguments from the remote path. Zed will use your SSH config to resolve host aliases, identity files, and ports.

What Happens During First Connection

On the first connection to a remote host, Zed performs several setup steps automatically:

This initial setup can take 10–30 seconds depending on network speed and project size. Subsequent connections are much faster because the server binary is cached.

Configuration and Settings

Zed's remote development respects both local and remote settings. Understanding how these interact is essential for a smooth workflow.

Local Settings

Your local settings.json controls UI-related preferences, keybindings, and theme. These always apply to the local Zed client regardless of whether you're editing local or remote files:

// ~/.config/zed/settings.json (local)

{
  "theme": "One Dark",
  "buffer_font_size": 14,
  "tab_size": 4,
  "soft_wrap": "preferred_line_length",
  "preferred_line_length": 100,
  "features": {
    "remote development": true
  },
  "ssh_connections": [
    {
      "host": "dev-server",
      "projects": [
        {
          "paths": ["/home/developer/my-project"]
        }
      ]
    },
    {
      "host": "gpu-box",
      "projects": [
        {
          "paths": ["/home/ml-engineer/training-pipeline"]
        }
      ]
    }
  ]
}

The ssh_connections array lets you pre-configure remote hosts and their associated project paths. These appear in the remote projects picker, saving you from typing paths repeatedly.

Remote Settings

Settings that affect language servers, formatters, and project-level behavior should live in a .zed directory within the remote project itself. This ensures that anyone connecting to the project gets the same configuration:

// /home/developer/my-project/.zed/settings.json (remote)

{
  "languages": {
    "Rust": {
      "language_servers": ["rust-analyzer"],
      "format_on_save": "on",
      "formatter": "language_server"
    },
    "Python": {
      "language_servers": ["pyright", "ruff"],
      "format_on_save": "on",
      "formatter": {
        "code_actions": {
          "source.organizeImports.ruff": true,
          "source.fixAll.ruff": true
        }
      }
    },
    "TypeScript": {
      "language_servers": ["typescript-language-server", "eslint"],
      "format_on_save": "on",
      "formatter": "prettier"
    }
  },
  "lsp": {
    "rust-analyzer": {
      "initialization_options": {
        "check": {
          "command": "clippy"
        },
        "cargo": {
          "features": "all"
        }
      }
    }
  }
}

Because this file lives on the remote host, the language server configuration is applied where the servers actually run — ensuring correct behavior and avoiding mismatches between local and remote environments.

Environment Variables

Language servers and terminal sessions on the remote host inherit the environment from the SSH login shell. If your project requires specific environment variables, define them in the remote shell profile or in a project-specific .envrc file used with direnv:

# /home/developer/my-project/.envrc (remote)

export DATABASE_URL="postgres://localhost:5432/myapp_dev"
export REDIS_URL="redis://localhost:6379"
export RUST_LOG="debug"
export PATH="$HOME/.cargo/bin:$PATH"

# Load language-specific environment
use_nix  # if using Nix flakes

Zed's remote terminal sessions source this file automatically when you cd into the project directory, provided direnv is installed on the remote host.

Working with Remote Terminals

Zed's integrated terminal works transparently with remote projects. When you open a terminal in a remote project, it spawns a shell on the remote host with the project directory as the working directory.

Opening a Remote Terminal

Terminal Configuration

You can customize the remote shell experience in your local settings:

// ~/.config/zed/settings.json (local)

{
  "terminal": {
    "shell": {
      "program": "zsh"
    },
    "font_family": "JetBrains Mono",
    "font_size": 13,
    "blinking": "on",
    "alternate_scroll": "on"
  }
}

Note that the shell.program value must be available on the remote host. If you specify fish but the remote machine only has bash, the terminal will fall back to the default login shell.

Language Server Configuration on Remote Hosts

One of the most important aspects of remote development is ensuring that language servers are installed and properly configured on the remote machine. Zed will attempt to start configured language servers, but they must be available in the remote $PATH.

Installing Language Servers Remotely

Here's a script you can run on the remote host to install common language servers:

#!/bin/bash
# install-language-servers.sh — run on the remote host

set -euo pipefail

echo "Installing language servers..."

# Rust
rustup component add rust-analyzer

# Python
pip install --user pyright ruff-lsp python-lsp-server

# TypeScript / JavaScript
npm install -g typescript typescript-language-server prettier eslint vscode-langservers-extracted

# Go
go install golang.org/x/tools/gopls@latest

# C / C++
# Requires clangd from LLVM
sudo apt-get install -y clangd  # Debian/Ubuntu

# YAML, JSON, Markdown
npm install -g yaml-language-server vscode-json-languageserver marksman

echo "Language server installation complete."

Run this script once on each remote host to ensure Zed can find the servers it needs. You can verify availability with which rust-analyzer, which pyright-langserver, and so on.

Custom Language Server Paths

If a language server is installed in a non-standard location on the remote host, you can specify its path in the remote project settings:

// /home/developer/my-project/.zed/settings.json (remote)

{
  "lsp": {
    "rust-analyzer": {
      "binary": {
        "path": "/home/developer/.cargo/bin/rust-analyzer",
        "arguments": []
      }
    },
    "pyright": {
      "binary": {
        "path": "/home/developer/.local/bin/pyright-langserver",
        "arguments": ["--stdio"]
      }
    }
  }
}

Managing Remote Connections

Zed provides several tools for managing your remote development sessions.

Viewing Active Connections

Use the command palette and search for remote: open to see all available commands related to remote development. Key commands include:

Reconnecting After Network Interruption

Zed automatically attempts to reconnect if the SSH connection drops. If reconnection fails, you'll see a notification with options to retry or disconnect. Unsaved buffer changes are preserved locally and synced once the connection is restored.

Killing Stale Remote Server Processes

If a remote server process becomes unresponsive, you can manually clean it up on the remote host:

# List running Zed remote server processes
ps aux | grep zed-remote-server

# Kill all Zed remote server processes
pkill -f zed-remote-server

# Alternatively, remove the installed binary to force a fresh download
rm -rf ~/.local/share/zed/remote_server/

After cleaning up, reconnect from Zed and it will redeploy a fresh server binary.

Multiplayer and Collaboration on Remote Projects

Zed's collaboration features work with remote projects. You can invite teammates to join your remote session, and they'll connect to the same remote host with shared cursors, buffers, and terminals.

Starting a Collaborative Session

Each collaborator's edits are applied on the remote host, and all participants see changes in real time. This is particularly powerful for pair programming on infrastructure that only one person has direct access to.

Best Practices

Optimize SSH for Low Latency

Network latency is the single biggest factor affecting remote development responsiveness. Configure SSH with connection multiplexing and compression to minimize overhead:

# ~/.ssh/config

Host dev-server
    HostName 10.0.0.42
    User developer
    IdentityFile ~/.ssh/id_ed25519
    Compression yes
    ControlMaster auto
    ControlPath ~/.ssh/cm-%r@%h:%p
    ControlPersist 30m
    ServerAliveInterval 30
    ServerAliveCountMax 5
    TCPKeepAlive yes

Keep Projects Focused

Avoid opening enormous monorepos as a single project if you only work in a small portion. Zed indexes the entire project directory, so narrowing the scope improves indexing speed and reduces memory usage on the remote host. Open subdirectories directly:

# Instead of opening the entire monorepo
zed ssh dev-server -- /home/developer/huge-monorepo

# Open just the service you're working on
zed ssh dev-server -- /home/developer/huge-monorepo/services/api-gateway

Use Remote-Specific .gitignore and .zedignore

If your project contains large generated directories that don't need indexing, create a .zedignore file on the remote host:

# /home/developer/my-project/.zedignore

node_modules/
target/
dist/
build/
*.log
.venv/
__pycache__/
.next/
.cache/

This prevents Zed from wasting resources indexing files you'll never edit.

Pin Language Server Versions

In team environments, inconsistent language server versions can cause confusing behavior. Pin versions in a setup script or use a tool like mise or asdf on the remote host:

# /home/developer/.tool-versions (remote)

rust-analyzer 2024-09-23
pyright 1.1.380
typescript-language-server 4.3.3
gopls 0.16.2

Monitor Remote Resource Usage

The Zed remote server consumes CPU and memory on the remote host. For large projects, monitor its impact:

# Monitor Zed remote server resource usage
top -p $(pgrep -f zed-remote-server | tr '\n' ',' | sed 's/,$//')

# Check memory usage
ps -o pid,rss,vsz,comm -p $(pgrep -f zed-remote-server)

# Disk usage of Zed's remote installation
du -sh ~/.local/share/zed/

If the remote server is consuming too much memory, consider narrowing the project scope or increasing the remote host's available RAM.

Secure Your SSH Keys

Since remote development depends entirely on SSH access, protect your private keys diligently. Use hardware security keys (YubiKey, etc.) where possible, and never copy private keys to shared or untrusted machines. Consider using SSH certificates issued by your organization's CA for short-lived, auditable access.

Use Jump Hosts for Layered Security

If your remote development hosts are behind a bastion or jump host, configure SSH proxy jumps so Zed can reach them transparently:

# ~/.ssh/config

Host bastion
    HostName bastion.example.com
    User jump-user
    IdentityFile ~/.ssh/id_ed25519

Host internal-dev
    HostName 10.0.0.42
    User developer
    IdentityFile ~/.ssh/id_ed25519
    ProxyJump bastion

Zed will follow the ProxyJump directive automatically, tunneling through the bastion to reach the internal host.

Troubleshooting Common Issues

Connection Times Out

If Zed hangs while connecting to a remote host, check the following:

# Test SSH connectivity manually
ssh -v dev-server "echo ok" 2>&1 | tail -20

# Check if the remote server port is reachable
nc -zv dev-server 22

# Verify the remote host has enough disk space for the server binary
ssh dev-server "df -h ~"

Common causes include full disk on the remote host, firewall rules blocking the SSH port, or an incorrect path in ~/.ssh/config.

Language Server Not Starting

If diagnostics and autocomplete aren't working, the language server may not be installed or may be crashing. Check the Zed logs:

# View Zed's logs (local)
# macOS:
cat ~/Library/Logs/Zed/Zed.log | grep -i "lsp\|language_server"

# Linux:
cat ~/.local/share/zed/logs/Zed.log | grep -i "lsp\|language_server"

# Check if the language server binary exists on the remote host
ssh dev-server "which rust-analyzer && rust-analyzer --version"

File Changes Not Syncing

If files modified outside of Zed (e.g., by a build tool or another editor) aren't reflected in the editor, force a reload:

Conclusion

Zed's remote development feature delivers a compelling combination of local-class editor responsiveness with the power and flexibility of remote infrastructure. By running a dedicated server process on the remote host, Zed avoids the pitfalls of network filesystem mounts and browser-based IDEs, giving you a native editing experience even when your code lives thousands of miles away. By following the setup steps, configuration patterns, and best practices outlined in this guide, you can establish a fast, secure, and consistent remote development workflow that scales from individual projects to team-wide collaboration. As Zed continues to evolve, remote development remains one of its most strategically important capabilities — bridging the gap between the speed of a local editor and the reality of distributed, cloud-based development environments.

— Ad —

Google AdSense will appear here after approval

← Back to all articles