← Back to DevBytes

Zed Debugging: Complete Guide

Introduction to Zed Debugging

Zed is a high-performance, multiplayer code editor built in Rust by the creators of Atom. While Zed is renowned for its blazing speed and minimal footprint, it also ships with robust debugging capabilities that integrate tightly with the Debug Adapter Protocol (DAP). This guide walks you through everything you need to know to debug applications effectively inside Zed, from initial setup to advanced workflows.

What Is Zed Debugging?

Zed debugging refers to the set of features inside the Zed editor that allow you to launch, attach to, and inspect running programs. Rather than reinventing the wheel, Zed leverages the Debug Adapter Protocol — the same open standard popularized by VS Code — to communicate with language-specific debug adapters. This means that if a debug adapter exists for your language, you can almost certainly use it inside Zed.

At its core, Zed debugging lets you set breakpoints, step through code, inspect variables, evaluate expressions, watch call stacks, and view runtime output — all without leaving the editor window.

Why Debugging in Zed Matters

Prerequisites and Setup

Before you can debug in Zed, you need three things: the Zed editor itself (stable or preview build), a debug adapter for your target language, and a project with a valid debug configuration file.

Installing a Debug Adapter

Zed does not bundle debug adapters. Instead, it downloads them on demand the first time you launch a debug session for a given language. For example, debugging a Python project will trigger Zed to fetch the debugpy adapter. You can also pre-install adapters manually if you prefer offline workflows.

Common adapters include:

Creating a Debug Configuration

Zed stores debug configurations in a .zed/debug.json file at the root of your project. This file defines one or more named "launch configurations" that describe how to start or attach to a program. Here is a minimal example for a Node.js project:

[
  {
    "label": "Run Current File",
    "adapter": "JavaScript",
    "program": "$ZED_FILE",
    "request": "launch",
    "type": "pwa-node"
  }
]

Each entry in the array is a separate configuration you can select from the debug panel. The label is what appears in the UI, the adapter tells Zed which debug adapter to use, and the remaining fields mirror the DAP launch request payload.

Launching Your First Debug Session

Once your .zed/debug.json file is in place, you can start debugging. Open the debug panel using the command palette (cmd-shift-p on macOS, ctrl-shift-p on Linux) and search for "debugger: toggle". Alternatively, use the keyboard shortcut cmd-shift-d / ctrl-shift-d.

Step-by-Step Workflow

Working with Breakpoints

Breakpoints are the foundation of any debugging workflow. Zed supports several breakpoint types beyond the simple line breakpoint.

Standard Breakpoints

Click the gutter to toggle a breakpoint on a line. You can also use F9 when the cursor is on the desired line. Breakpoints persist across sessions as long as the file remains in the project.

Conditional Breakpoints

Right-click the gutter and choose "Edit Breakpoint" to add a condition or hit count. A conditional breakpoint only pauses when the expression evaluates to true. This is invaluable for debugging loops:

// Break only when the counter exceeds 1000
counter > 1000

// Break only on every 50th hit
hitCount % 50 == 0

Logpoints

Logpoints let you print messages to the debug console without modifying your source code. They appear as diamond-shaped icons in the gutter. Use them when you want to trace execution in production-like scenarios where editing files is undesirable.

Stepping Through Code

Once paused at a breakpoint, Zed provides the standard stepping controls:

These shortcuts can be customized in your keymap.json file if you prefer different bindings.

Inspecting State

Variables Pane

The variables pane displays all in-scope local variables, arguments, and closures. Expand objects and arrays to drill into nested structures. Right-click any variable to copy its value or add it to the watch list.

Watch Expressions

For values you want to monitor across multiple steps, add them to the watch pane. Watch expressions are re-evaluated after every pause, making them ideal for tracking derived state:

users.filter(u => u.active).length
request.headers["authorization"]
state.todos[0].completed

Call Stack Pane

The call stack pane shows the chain of function calls that led to the current pause point. Click any frame to jump to that location in the source and inspect its local scope. This is essential for understanding how you arrived at an unexpected state.

Debug Console / REPL

The debug console lets you evaluate arbitrary expressions in the context of the paused frame. Use it to test hypotheses, call methods, or mutate state on the fly:

> user.validate()
true
> user.email = "test@example.com"
"test@example.com"
> db.query("SELECT COUNT(*) FROM orders")
{ count: 42 }

Language-Specific Examples

Debugging Python

For a Python project, your .zed/debug.json might look like this:

[
  {
    "label": "Python: Current File",
    "adapter": "Python",
    "request": "launch",
    "program": "$ZED_FILE",
    "console": "integratedTerminal",
    "justMyCode": true
  }
]

Ensure debugpy is installed in your environment:

pip install debugpy

Debugging Rust

Rust debugging typically uses codelldb. Build your binary with debug symbols and configure Zed accordingly:

[
  {
    "label": "Debug Rust Binary",
    "adapter": "LLDB",
    "request": "launch",
    "program": "${workspaceFolder}/target/debug/my_app",
    "stopOnEntry": false
  }
]

Compile with:

cargo build

Debugging Go

Go uses Delve. Install it first:

go install github.com/go-delve/delve/cmd/dlv@latest

Then configure Zed:

[
  {
    "label": "Debug Go Package",
    "adapter": "Delve",
    "request": "launch",
    "mode": "debug",
    "program": "${workspaceFolder}"
  }
]

Attaching to a Running Process

Sometimes you need to debug a process that is already running — for example, a web server started by a container orchestrator. Use "request": "attach" instead of "launch":

[
  {
    "label": "Attach to Node Process",
    "adapter": "JavaScript",
    "request": "attach",
    "processId": "${command:pickProcess}",
    "type": "pwa-node"
  }
]

For Python, start the target process with debugpy in listen mode:

python -m debugpy --listen 5678 --wait-for-client my_script.py

Then attach:

[
  {
    "label": "Attach to Python on 5678",
    "adapter": "Python",
    "request": "attach",
    "connect": {
      "host": "localhost",
      "port": 5678
    }
  }
]

Best Practices

Troubleshooting Common Issues

Breakpoints Not Hit

If your breakpoints appear as hollow gray circles instead of solid red dots, the debug adapter cannot map the breakpoint to executable code. Common causes include stale build artifacts, source maps pointing to outdated files, or optimizations stripping debug symbols. Rebuild your project and ensure debug info is enabled.

Adapter Fails to Download

Behind a corporate proxy or firewall, Zed may be unable to fetch adapters automatically. Set the HTTPS_PROXY environment variable before launching Zed, or pre-install the adapter manually and point Zed to it via your settings.

Variables Show "Not Available"

This usually means the program was compiled with optimizations that inline or eliminate variables. Recompile with -O0 (C/C++), --debug (Rust), or remove minification (JavaScript) to preserve variable info.

Conclusion

Debugging in Zed combines the speed and simplicity of a lightweight editor with the full power of the Debug Adapter Protocol. By mastering breakpoints, stepping controls, variable inspection, and language-specific configurations, you can diagnose issues faster and with greater confidence. As Zed continues to evolve, its debugging story will only grow richer — but the fundamentals covered here will remain the backbone of an efficient workflow. Start with a simple launch configuration, get comfortable with the keyboard shortcuts, and gradually incorporate advanced techniques like conditional breakpoints, logpoints, and attach mode as your needs expand.

— Ad —

Google AdSense will appear here after approval

← Back to all articles