← Back to Blog
Developer Tools

Zed Remote Development: SSH, Tasks and Local Previews

Keep Zed's editor interface local while working in an authorized remote development checkout. This documentation-based guide separates settings, saved task input and localhost previews, with proposed checks and clear trust and AI privacy boundaries.

Written by Hamza Diaz
October 28, 202610 min read17 views

Imagine moving a small web project to an existing development host. The editor still looks familiar. But which machine runs a task, and where does your browser's localhost point? Those are the questions to settle before changing settings.

Zed remote development connects your local editor to a checkout over SSH. The interface stays on your laptop; language servers, tasks and terminals run on the remote host. Zed's remoting documentation explains the split.

The examples below are documentation-based proposals. None was executed for this article: no Zed installation or SSH session was tested, and no application, port or AI call was validated. Use the guide to plan a setup and diagnose its boundaries.

What stays local and what runs on the remote host

Map the editor, checkout and execution paths

Start with where the work happens. A local-looking window tells you little about the process behind it. The documented architecture assigns each component a location:

ComponentLocationPractical implication
Editor UI and Tree-sitter parsingLocal machineDisplayed content is processed locally
Unsaved changes and recent-project stateLocal machineRemote checkout does not mean no local copies
Source checkoutRemote hostSaved project files belong to that checkout
Language servers, tasks and terminalsRemote hostInspect the remote toolchain and working directory
AI requestsSeparate configured pathReview provider and agent routing independently

An existing host with tools or data your project needs gives you a reason to work remotely. The connection alone gives you neither a reproducible environment nor evidence of better performance.

Treat AI requests as a separate path

AI needs its own review. The remoting overview describes local model communication, while Zed's AI privacy documentation distinguishes request paths for provider keys, gateways, external agents and Terminal Threads. You cannot infer where a prompt goes from where the checkout lives.

Start with an authorized host and a dedicated development checkout

Confirm SSH access without weakening verification

This guide assumes you already have authorized access to a development host. Prepare its toolchain independently and choose a dedicated, non-production checkout. The hostname devbox.example.com is fictional; substitute your approved host when planning the connection.

In Zed's Remote Projects dialog, choose Connect New Server and supply the approved SSH connection. Zed uses your local SSH binary and configuration; its connection documentation recommends key-based authentication for repeated connections. Keep host-key verification enabled and follow your organization's access process. A connection error is a reason to investigate, never a reason to put private keys in project settings or disable verification.

Select the project folder itself. The same documentation warns against opening oversized roots, including the filesystem root or an entire home directory.

Check the remote server and toolchain prerequisites

The host needs a matching Zed server binary. The remote-development documentation lists macOS, Linux and Windows hosts with qualifications, including non-exhaustive Linux distribution testing. Read the requirements for your actual host before committing to the setup.

Use this preparation checklist:

  • Your approved SSH access works without weakening verification.
  • The remote platform can run the matching Zed server.
  • The dedicated checkout and project runtime already exist.
  • The server binary has an approved download or delivery path.

The documented upload_binary_over_ssh option downloads the server binary locally, then uploads it over SSH. Project dependencies still need separate preparation, and the option does not make every feature available offline. The checklist above remains proposed until you verify it on your host.

Put settings and runtime checks in the right place

Separate local, server and project settings

A settings change only helps if the process that needs it reads it. Both Zed processes read project settings, but neither reads the other's main settings file. The settings documentation gives you the scope to choose:

NeedSettings scopeAvoid
Font size and editor appearanceLocalChanging server settings to fix the UI
Remote language-server paths or proxyServerAssuming the laptop's proxy applies remotely
Portable indentation or formatter choiceProjectCommitting machine-specific paths or secrets

Keep machine-specific paths out of shared configuration. Otherwise, the next person opening the checkout inherits a dependency on your filesystem.

Check the remote runtime without dumping the environment

For a Node.js project on a Unix-like development host, consider these read-only checks in the remote terminal. Assume a POSIX-style shell, an available hostname utility and an installed Node.js runtime. Running them in a separate laptop shell answers the wrong question.

hostname
pwd
command -v node
node --version

With no argument, hostname prints the host name; pwd reports the working directory. command -v reports shell command resolution, which can identify an alias or function rather than an executable path. node --version prints Node.js's version. The hostname reference documents command behavior, not Zed support for OpenBSD.

Inspect the results privately. Does the host match the intended machine? Does the directory belong to the checkout? Compare the discovered runtime with the project's requirements. If command discovery fails, resolve it before requesting the version. No output or expected version is asserted here, and there is no need to share sensitive hostnames or dump the full environment.

A terminal success only answers the terminal question. Zed's environment documentation describes different handling for CLI and graphical launches, tasks, terminals and language-server lookup. Check language-server binary discovery separately. Do not assume laptop variables or secrets are forwarded automatically.

For Python packaging projects, the uv build and publish checklist addresses a further boundary: a working checkout is not proof that the distributed package works.

Make remote tasks use the intended directory, saved file and context

Choose task scope and save policy deliberately

Put project tasks in .zed/tasks.json. Global tasks are available across projects. Zed's task documentation defines both scopes and sets the default working directory to the current project root.

This proposed project-task definition only prints that directory on a Unix-like host:

[
  {
    "label": "inspect-task-directory",
    "command": "pwd",
    "save": "none"
  }
]

Writing that file changes configuration even though pwd is read-only. The example has not been installed or run. Its label is a machine identifier, and its command reports the working directory. If you add an explicit cwd for a subproject, use the intended remote directory. A laptop path will not identify it.

The save default deserves attention. With none, an edited buffer can differ from the file a tool reads. Choose current to save the active buffer or all to save every edited buffer, as documented in the task reference. Check which files that choice would change before adopting it.

For a later file-based task, follow the task documentation's separation of command and args, including its handling of variables in paths with spaces. This pwd example has no file argument. It tells you nothing about which input a test would read.

Distinguish rerun context from terminal reuse

Selecting a different file does not necessarily change a rerun. By default, Zed reuses resolved context, including previously captured file variables. The rerun control example places reevaluate_context on the task::Rerun action in a keybinding. It is not a task-template field.

Terminal reuse controls something else. The documented defaults reuse a terminal and wait for the previous task to finish. A new tab will not select a different host or file. Concurrency will not resolve an input mismatch either.

Before running the project's actual command, inspect the checkout and working directory, then check the saved input against the resolved context. A successful directory print leaves application tests unverified.

Trace a remote web app to a localhost browser preview

Separate the application listener from the SSH forward

For a hypothetical preview, suppose you independently start a development app on the remote host's loopback port 3000. The app sits outside this guide's setup. Its installation and startup recipe are neither supplied nor executed here.

This proposed fragment maps local port 8080 to the remote port using Zed's documented ssh_connections.port_forwards configuration. Merge it into the connection for your authorized host, preserving the rest of your connection list.

{
  "ssh_connections": [
    {
      "host": "devbox.example.com",
      "port_forwards": [
        { "local_port": 8080, "remote_port": 3000 }
      ]
    }
  ]
}

Trace the intended request path to the app that is already running:

flowchart TD A[Local browser: port 8080] --> B[Local SSH forward] B --> C[Remote loopback: port 3000] C --> D[Running development app]

The forward cannot start the app. If the preview fails, first check whether the app is listening. Then investigate the forwarding route, including local port conflicts and the remote destination. Having a tunnel configured leaves application readiness unverified.

Keep the preview bound to localhost

Zed's forwarding defaults bind both endpoints to localhost. Keep them for this preview. Setting local_host to 0.0.0.0 binds all local interfaces. Configure the intended connection and forward before visiting http://localhost:8080; the browser's localhost still refers to your laptop.

Loopback binding supplies neither application authentication nor public deployment. Once you can reach the intended app, Playwright accessibility state testing offers a separate application-checking task. Reaching the preview does not establish a test pass.

Use the Host-Task-Preview playbook to check one development project

Host-Task-Preview is the editorial checklist proposed in this guide. It combines the documented boundaries into a decision matrix; it is neither a Zed feature nor an industry standard, and it has not been tested as a deployment method.

Host: identify the checkout and configuration scope

Use one non-sensitive development checkout. Settle which host and settings scope you are inspecting before diagnosing the application.

Task: inspect the runtime and saved input

Read the command's inputs as carefully as its label. Check language-server behavior separately from terminal results.

Preview: check the listener and browser route

Follow the request until you find the first mismatch. Correct that layer before changing another setting.

StageProposed checkPrivate evidence to inspectMismatch suggests
HostIdentify host, checkout and settings scopeIntended machine and dedicated directoryWrong connection, root or configuration scope
TaskInspect runtime, cwd, save policy and contextIntended binary and saved fileToolchain or input mismatch
PreviewSeparate listener, forward and browserIntended app at intended local destinationApp readiness or routing problem

Keep a small record during the trial. These observations support a decision about the setup; they do not measure a performance gain.

Record privatelyWhenDecision supported
Runtime and configuration differencesBefore adopting the checkoutResolve toolchain mismatch
Saved-input or rerun-context mismatchesDuring normal developmentRevise the task definition
Preview failures by listener or forwarding causeWhen previewing failsFix the responsible layer
Setup and maintenance effortDuring the initial trialKeep remote or return local

For a machine-readable planning record, the same boundaries can be represented as follows. Its status remains proposed and unexecuted.

{
  "framework": "host-task-preview",
  "checks": ["authorized-checkout", "saved-task-input", "running-app-and-local-forward"],
  "status": "proposed-unexecuted"
}

Before adding repositories or sensitive data, make sure you can explain each path and access boundary. Keep notes private and omit credentials or full environment dumps. This article records no completed checklist.

Common mistakes and limits: SSH is not a sandbox or an AI privacy policy

Correct the assumption before changing the setting

Watch for these diagnostic mistakes:

  • Checking the laptop's runtime when the task runs remotely.
  • Opening a whole home directory instead of the project.
  • Assuming rerun follows the newly selected file.
  • Expecting unsaved edits to be the tested input.
  • Forwarding a port before the application is listening.

Each points back to a specific row in the decision matrix. Use it to isolate the problem.

Review worktree trust and AI routing separately

Zed keeps worktree-trust records separately for each SSH host. Restricted Mode prevents applying project settings and installing or starting their untrusted language and MCP servers; globally trusted tools can still run. Review the project's configuration and instructions, along with the tools it can invoke, before granting trust. Blanket trust is a poor fix for a permission question. Worktree trust does not provide a complete sandbox.

For AI, inspect the chosen request path and provider terms. External agents and terminal-based tools can manage their own authentication, routing and permissions, as Zed's privacy guidance explains. SSH transport gives you no universal guarantee about retention, training or confidentiality.

If your chosen path includes a gateway, the Vercel AI Gateway guide has a separate checklist for routing and provider policy. That link does not imply your Zed session uses the gateway. Basic remote editing needs no AI call; Zed's AI Quick Start points to the Settings Editor's Disable AI control.

Know when to keep the project local

Remote development should earn its maintenance cost. Weigh administration and toolchain preparation against the work it helps you do. Check platform support, connection reliability and ongoing maintenance too. If you enable AI, review provider behavior and data policy. Savings or lower latency need evidence from your own workload.

Keep normal saving and version-control practices; reconnecting is no backup strategy. If nobody can maintain the host's access boundary, keep the project local. Otherwise, start with the smallest checkout whose location solves a real development problem. Expand after you understand its execution and preview paths.

Key Takeaways

  • 1Zed's interface stays local while language servers, tasks and terminals run on the remote development host.
  • 2Local, server and project settings serve different purposes and do not automatically synchronize.
  • 3Inspect saved input and resolved rerun context before assuming a task follows the active file.
  • 4A browser preview needs an independently running remote app and the intended localhost-bound forward.
  • 5Worktree trust and SSH do not establish a complete sandbox or universal AI privacy guarantees.
  • 6Use Host-Task-Preview on one non-sensitive checkout, with private evidence rather than assumed success.

Conclusion

Start with one non-sensitive checkout and use Host-Task-Preview to find mismatches before expanding. Confirm the settings scope and remote runtime, then inspect saved task input. For a web preview, follow the browser request through the forward to the running app. Review AI routing on its own terms. These checks help explain the setup; they cannot certify security, reproducibility or performance. Keep the project local if maintaining the host adds work without solving a concrete development need.

Frequently Asked Questions

What runs locally and remotely in Zed remote development?

The editor UI, Tree-sitter parsing and unsaved-change state remain local. The source checkout, language servers, tasks and terminals run on the remote host. Review AI request routing separately; it does not simply inherit the checkout's location.

Where should I put Zed settings for a remote project?

Use local settings for the interface, server settings for remote tool paths and proxy configuration, and project settings for portable project behavior. Both sides read project settings, but neither reads the other's main settings file.

Why can a Zed task use an older file or previous selection?

Zed defaults to saving no buffers before a task, and reruns normally reuse resolved context. Inspect the saved file and captured variables. Choose a deliberate save policy and the documented `task::Rerun` action argument `reevaluate_context` when fresh context is intended.

How can I preview a remote development app in my local browser?

Start the app separately on the remote host, configure a localhost-bound SSH forward to its listening port, then visit the chosen local port. A forward neither launches nor authenticates the app; check application readiness separately.

Does Zed over SSH keep code and AI prompts entirely on the remote host?

No such guarantee follows from SSH. Displayed content and unsaved state can exist locally. Providers, gateways, external agents and terminal-based AI tools have separate request paths, permissions and terms. Worktree trust is also not complete process isolation or a reproducible environment.

Sources

Share this article

Hamza Diaz

Written by

Hamza Diaz

Hamza Diaz is the founder of Optijara, where he builds practical AI agents, automation systems, and Copilot workflows for service businesses. He writes about AI operations, agent strategy, and real-world implementation for teams that want usable systems instead of hype.