← Back to DevBytes

Zed Terminal Integration: Complete Guide

Zed Terminal Integration: Complete Guide

Zed is a next-generation code editor built in Rust by the creators of Atom. One of its standout features is the deeply integrated terminal, which allows developers to run shell commands, scripts, and build tools without ever leaving the editor. This guide walks you through everything you need to know to master Zed's terminal integration, from basic usage to advanced configuration and best practices.

What Is Zed Terminal Integration?

Zed's terminal integration is a built-in, GPU-accelerated terminal emulator that lives inside the editor. Unlike external terminal windows or loosely coupled plugins, Zed's terminal shares the editor's rendering pipeline, theming system, and workspace context. This means your terminal inherits your color scheme, font, and keybindings, and it can be opened as a docked panel or as a full editor tab.

The terminal is powered by alacritty_terminal, the same high-performance backend used by the Alacritty terminal emulator. This gives Zed near-instant input latency and smooth scrolling, even when dumping thousands of lines of output from a build log or test runner.

Why Terminal Integration Matters

Context switching is one of the biggest productivity killers for developers. Every time you alt-tab to an external terminal, you break your flow. Zed's integrated terminal eliminates that friction by keeping your shell right next to your code. Here are the key benefits:

Opening the Terminal

Zed provides several ways to open the integrated terminal. The default keybindings differ slightly between operating systems, but the core commands are consistent.

You can also open a terminal as a full editor tab instead of a docked panel. Use the command palette and select terminal: open to get a terminal that behaves like any other editor tab, complete with split view support.

Configuring the Terminal

Zed stores its configuration in a single JSON file. On macOS, this is located at ~/.config/zed/settings.json, and on Linux it is at ~/.config/zed/settings.json as well. You can open it directly from Zed using Cmd/Ctrl + , or through the command palette by searching for zed: open settings.

The terminal-specific settings live under the terminal key. Here is a comprehensive example:

{
  "terminal": {
    "shell": {
      "program": "zsh",
      "args": ["-l"]
    },
    "working_directory": "current_project_directory",
    "font_family": "JetBrains Mono",
    "font_size": 13,
    "line_height": "comfortable",
    "blinking": "terminal_controlled",
    "alternate_scroll": "off",
    "env": {
      "EDITOR": "zed --wait",
      "VISUAL": "zed --wait",
      "COLORTERM": "truecolor"
    },
    "toolbar": {
      "title": true
    },
    "button": false
  }
}

Let's break down the most important options:

Choosing Your Shell

By default, Zed uses your system's default shell, which it detects from the SHELL environment variable. You can override this in the configuration. Here are common setups for different shells:

Using Bash:

{
  "terminal": {
    "shell": {
      "program": "bash",
      "args": ["-l"]
    }
  }
}

Using Fish:

{
  "terminal": {
    "shell": {
      "program": "fish",
      "args": ["-l"]
    }
  }
}

Using Nushell:

{
  "terminal": {
    "shell": {
      "program": "nu",
      "args": []
    }
  }
}

Using a shell launched through tmux:

{
  "terminal": {
    "shell": {
      "program": "tmux",
      "args": ["new-session", "-A", "-s", "zed"]
    }
  }
}

The tmux example is particularly powerful because it gives you persistent sessions that survive even if Zed is closed and reopened.

Custom Keybindings for the Terminal

Zed allows you to define custom keybindings in ~/.config/zed/keymap.json. You can target terminal-specific contexts using the Terminal context tag. Here is an example keymap that adds useful terminal shortcuts:

[
  {
    "context": "Terminal",
    "bindings": {
      "ctrl-shift-c": "terminal::copy",
      "ctrl-shift-v": "terminal::paste",
      "cmd-k": "terminal::clear",
      "ctrl-shift-t": "terminal::new",
      "ctrl-shift-w": "terminal::close",
      "ctrl-tab": "terminal::next",
      "ctrl-shift-tab": "terminal::previous",
      "alt-left": "terminal::word_left",
      "alt-right": "terminal::word_right"
    }
  },
  {
    "context": "Workspace",
    "bindings": {
      "ctrl-`": "terminal_panel::toggle",
      "ctrl-shift-`": "terminal_panel::new"
    }
  }
]

Key things to understand about terminal keybindings:

Working with Multiple Terminals

Zed supports multiple terminal instances within a single workspace. Each terminal appears as a tab in the terminal panel, and you can switch between them using the tab bar or keyboard shortcuts. This is useful when you need one terminal for a dev server, another for running tests, and a third for Git operations.

To open a new terminal tab, use the + button in the terminal panel header, or press your configured terminal::new shortcut. You can also split the terminal panel horizontally or vertically, just like editor panes, by using the command palette and selecting terminal: split.

Here is a practical workflow example. Imagine you are working on a Node.js project:

# Terminal 1: Start the dev server
npm run dev

# Terminal 2: Run tests in watch mode
npm test -- --watch

# Terminal 3: Git operations
git status
git add -A
git commit -m "feat: add user authentication"

With multiple terminal tabs, all three of these can run simultaneously without any window juggling.

Linking the Terminal to Your Editor

One of the most powerful integration features is the ability to open files from the terminal directly in Zed. By setting the EDITOR and VISUAL environment variables to zed --wait, any command that invokes an external editor will now use Zed. This works with Git, Docker, Kubernetes, and many other tools.

{
  "terminal": {
    "env": {
      "EDITOR": "zed --wait",
      "VISUAL": "zed --wait"
    }
  }
}

With this configuration, running git commit without the -m flag will open Zed's editor to compose your commit message. Similarly, crontab -e will open your crontab in Zed. The --wait flag is critical: it tells the calling process to block until you close the file in Zed, which is how the calling program knows you are done editing.

You can also manually open files from the terminal at any time:

# Open a single file
zed src/index.ts

# Open multiple files
zed src/index.ts src/utils/helpers.ts

# Open the current directory as a new project
zed .

Theming and Appearance

The terminal automatically inherits your active Zed theme. If you switch from a light theme to a dark theme, the terminal updates instantly. However, you can fine-tune terminal-specific appearance settings. The terminal supports ANSI 256 colors and true color (24-bit), which means modern tools like bat, exa/eza, delta, and starship will render correctly.

If you want to ensure true color support is enabled for all terminal sessions, add the COLORTERM environment variable:

{
  "terminal": {
    "env": {
      "COLORTERM": "truecolor"
    }
  }
}

You can also control the terminal's font independently from the editor. This is useful if you prefer a slightly smaller or larger font for terminal output, or if you want to use a Nerd Font for shell prompts like Starship or Powerlevel10k:

{
  "terminal": {
    "font_family": "JetBrainsMono Nerd Font",
    "font_size": 12
  }
}

Integrating with Build Systems and Task Runners

While Zed does not yet have a full task runner system like VS Code's tasks.json, you can simulate much of that functionality using shell aliases, functions, or scripts combined with the integrated terminal. A common pattern is to create a project-local script directory and add it to your PATH via the terminal environment configuration.

{
  "terminal": {
    "env": {
      "PATH": "./bin:${PATH}"
    }
  }
}

Then, in your project, create executable scripts:

#!/usr/bin/env bash
# bin/dev - Start the development environment

set -euo pipefail

echo "Starting development server..."
npm run dev &
DEV_PID=$!

echo "Starting test watcher..."
npm test -- --watch &
TEST_PID=$!

trap "kill $DEV_PID $TEST_PID 2>/dev/null" EXIT

wait

Make it executable and run it from the Zed terminal:

chmod +x bin/dev
dev

Using the Terminal with Language Servers and Debugging

Zed's terminal can complement the editor's built-in language server support. For example, while Zed handles code completion, go-to-definition, and inline diagnostics through LSP, you can use the terminal for tasks that LSP does not cover, such as running REPLs, interactive debuggers, or database clients.

Here are some practical examples:

# Start a Node.js REPL to test snippets
node

# Start a Python REPL with IPython
ipython

# Connect to a local PostgreSQL database
psql -d myapp_development

# Run a Ruby on Rails console
rails console

# Start a Rust REPL using evcxr
evcxr

Because the terminal is in the same workspace as your code, you can quickly copy a function or expression from your editor and paste it into the REPL for testing.

Best Practices

To get the most out of Zed's terminal integration, follow these best practices:

Troubleshooting Common Issues

The terminal does not inherit my shell configuration. Make sure you are launching a login shell by passing -l in the shell args. Without this, files like ~/.bash_profile or ~/.zprofile may not be sourced.

Colors look wrong in the terminal. Ensure COLORTERM is set to truecolor in the terminal environment configuration, and verify that your shell's RC file is not overriding it.

zed command not found inside the terminal. Install the Zed CLI by running zed: install cli from the command palette. On macOS, this places a symlink at /usr/local/bin/zed. On Linux, you may need to add Zed's bin directory to your PATH.

The terminal is slow with large outputs. While Zed's terminal is GPU-accelerated, extremely large outputs (millions of lines) can still cause lag. Consider piping large outputs through less or redirecting to a file:

# Pipe build output to a file and view it in Zed
npm run build 2>&1 | tee build.log
zed build.log

Keybindings conflict between terminal and editor. If a keybinding works in the editor but not the terminal (or vice versa), check your keymap.json for conflicting entries. Remember that terminal keybindings must be scoped to the Terminal context, and some keys (like Ctrl+C) are reserved by the terminal for signal handling.

Conclusion

Zed's terminal integration is more than just a convenience feature — it is a core part of the editing experience that blurs the line between code and command line. By configuring your shell, environment variables, keybindings, and appearance settings, you can create a seamless workflow where running a build, inspecting Git history, launching a REPL, and editing source files all happen within a single, high-performance window. Start with the basics: set your preferred shell, configure EDITOR to zed --wait, and gradually add custom keybindings and environment variables as your needs grow. With a little setup, the integrated terminal becomes an indispensable tool that keeps you in flow and focused on what matters — writing great code.

— Ad —

Google AdSense will appear here after approval

← Back to all articles