Zed
8 min read

High-performance code editor built in Rust by the creators of Atom and Tree-sitter. GPU-rendered UI (GPUI framework) — stays fast at any file size. Designed for speed, collaboration, and AI-assisted development.

Key Features

• GPU-rendered UI via GPUI — no Electron
• Tree-sitter for syntax and semantic parsing
• First-class LSP integration
• Vim mode (modal editing with LSP/Tree-sitter awareness)
• Inline AI editing, agent panel, edit prediction
• SSH remote development (UI local, everything else remote)
• Real-time collaboration via Channels
• Multi-buffer editing — compose views across multiple files
• Built-in debugger (DAP)
• Tasks system with editor context variables

Config using Nix

Home Manager module programs.zed-editor:

nix
programs.zed-editor = {
enable = true;
package = pkgs.zed-editor;
installRemoteServer = true; # symlinks headless server for SSH remote dev
defaultEditor = true; # sets $EDITOR and $VISUAL

# mutable = Zed can still write changes from the GUI
mutableUserSettings = true;
mutableUserKeymaps = true;

extensions = [ "toml" "nix" "catppuccin" "html" ];

userSettings = {
vim_mode = true;
theme = "Catppuccin Mocha";
buffer_font_family = "Zed Mono";
buffer_font_size = 14;
format_on_save = "on";
assistant = {
default_model = {
provider = "anthropic";
model = "claude-sonnet-4-6";
};
version = "2";
};
};

userKeymaps = [
{
context = "Editor && vim_mode == normal";
bindings = { "space f" = "file_finder::Toggle"; };
}
];

userTasks = [
{
label = "cargo check";
command = "cargo check";
cwd = "$ZED_WORKTREE_ROOT";
reveal = "always";
}
];
};

Important: by default Home Manager writes a read-only settings.json. Zed cannot modify read-only files, so GUI settings changes won't persist unless you set mutableUserSettings = true.

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

json
{
"vim_mode": true,
"theme": "One Dark",
"buffer_font_family": "Zed Mono",
"buffer_font_size": 14,
"tab_size": 2,
"hard_tabs": false,
"soft_wrap": "none",
"format_on_save": "on",
"autosave": "off",
"ensure_final_newline_on_save": true,
"remove_trailing_whitespace_on_save": true,
"cursor_shape": "bar",
"current_line_highlight": "all",
"show_edit_predictions": true,
"git": {
"git_gutter": "tracked_files",
"inline_blame": { "enabled": true }
},
"assistant": {
"default_model": {
"provider": "anthropic",
"model": "claude-sonnet-4-6"
}
},
"lsp": {
"rust-analyzer": {
"initialization_options": {
"check": { "command": "clippy" }
}
}
}
}

Key Settings

SettingDefaultDescription
vim_modefalseEnable Vim keybindings
helix_modefalseEnable Helix keybindings
base_keymap"VSCode"Base keymap style (VSCode/Atom/JetBrains/None)
buffer_font_size15Editor font size (6–100)
tab_size4Spaces per indent level
hard_tabsfalseUse tabs instead of spaces
soft_wrap"none"Line wrap mode
format_on_save"on"Auto-format on save
autosave"off"off / on_focus_change / on_window_change / after_delay
cursor_shape"bar"bar / block / underline / hollow
semantic_tokens"off"LSP semantic highlighting: off / combined / full
code_lens"off"LSP inline metadata: off / on / menu
inlay_hints—Type/param hints (object)
show_edit_predictionstrueAI inline edit suggestions
disable_aifalseDisable all AI features
formatter"auto"language_server / external / code_actions / none
preferred_line_length80Soft-wrap column

Settings can also be scoped per-language:

json
{
"languages": {
"Python": { "tab_size": 4, "format_on_save": "off" }
}
}

Project-level overrides go in .zed/settings.json at the worktree root.

Keybindings

Open the keymap editor: Cmd+K Cmd+S (macOS) / Ctrl+K Ctrl+S.
Custom bindings go in ~/.config/zed/keymap.json.


ActionmacOSLinux/Win
Command paletteCmd+Shift+PCtrl+Shift+P
Open fileCmd+PCtrl+P
Project symbol searchCmd+TCtrl+T
File symbol outlineCmd+Shift+OCtrl+Shift+O
Project searchCmd+Shift+FCtrl+Shift+F
Go to definitionF12F12
Find all referencesAlt+Shift+F12Alt+Shift+F12
Project panelCmd+Shift+ECtrl+Shift+E
Outline panelCmd+Shift+BCtrl+Shift+B
Tab switcherCtrl+TabCtrl+Tab

Editing

ActionmacOSLinux/Win
Multi-cursor (next match)Cmd+DCtrl+D
Select all matchesCmd+Shift+LCtrl+Shift+L
Rename symbolF2F2
Code actionsCmd+.Ctrl+.
Format documentCmd+Shift+ICtrl+Shift+I
Toggle commentCmd+/Ctrl+/
Move line up/downCtrl+Cmd+↑/↓Alt+↑/↓

Panes & Tabs

ActionmacOSLinux/Win
Split rightCmd+K →Ctrl+K →
Split downCmd+K ↓Ctrl+K ↓
Focus pane (direction)Cmd+K Cmd+←/→Ctrl+K Ctrl+←/→
Close tabCmd+WCtrl+W
Open terminal Ctrl+` Ctrl+`

Git

ActionmacOSLinux/Win
Stage allCmd+Ctrl+YCtrl+Space
CommitCmd+EnterCtrl+Enter
PushCtrl+G ↑Ctrl+G ↑
PullCtrl+G ↓Ctrl+G ↓
FetchCtrl+G Ctrl+GCtrl+G Ctrl+G

AI

ActionmacOSLinux/Win
Inline assistantCtrl+EnterCtrl+Enter
Accept edit predictionTabTab
Open agent panelCmd+?Ctrl+?
Generate commit messageAlt+TabAlt+L

Vim Mode

Enable with vim_mode: true or toggle via workspace: toggle vim mode.

Zed's Vim mode integrates with LSP and Tree-sitter rather than emulating Vim exactly.

LSP-aware commands

CommandAction
gdGo to definition
gDGo to declaration
cdRename symbol
g.Code actions
gAFind all references

Tree-sitter text objects

ObjectInnerAround
Functionifaf
Classicac
Argumentiaaa
HTML/XML tagitat

Tree-sitter motions

KeyAction
]m / [mNext/prev method
]] / [[Next/prev section

Git motions (Vim)

KeyAction
]c / [cNext/prev diff hunk
doExpand hunk
dOToggle staging

Built-in plugin equivalents

FeatureKeys
Surround addys<motion><char>
Surround changecs<old><new>
Surround deleteds<char>
Comment (normal)gcc
Comment (visual)gc
vim-exchangecx
ReplaceWithRegistergR

Vim settings

json
{
"vim": {
"default_mode": "normal",
"use_system_clipboard": "always",
"use_smartcase_find": true,
"toggle_relative_line_numbers": true,
"highlight_on_yank_duration": 200
}
}

Regex differences from Vim

Zed uses its own regex engine — capture groups use ( ) not \( \), backreferences use $1 not \1, and substitutions are global by default (no /g needed).

AI Features

Edit Prediction

Inline suggestions on each keystroke, accepted with Tab. Disable per file glob:

json
{
"edit_predictions": {
"disabled_globs": ["**/.env", "**/secrets/**"]
}
}

Inline Assistant

Select code → Ctrl+Enter → describe the change → model rewrites in place. Works on multiple cursors simultaneously.

Agent Panel

Full conversation interface for multi-step tasks. The agent can read/write files, run terminal commands, and use MCP tools. Open with Cmd+?.

Supported AI Providers

Anthropic, OpenAI, Google, GitHub Copilot, Ollama, Codestral, and others. Bring your own API key or use local models. Configure in settings:

json
{
"assistant": {
"default_model": {
"provider": "anthropic",
"model": "claude-opus-4-7"
},
"version": "2"
}
}

MCP (Model Context Protocol)

Extend the agent with external tools and data sources. Add servers to settings:

json
{
"context_servers": {
"my-server": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-github"],
"env": { "GITHUB_TOKEN": "${GITHUB_TOKEN}" }
},
"remote-server": {
"url": "https://example.com/mcp",
"headers": { "Authorization": "Bearer <token>" }
}
}
}

Also installable as Zed extensions (GitHub, Puppeteer, Brave Search, Figma, etc.).

Tool permissions:

json
{
"agent": {
"tool_permissions": {
"default": "confirm",
"mcp:my-server:read_file": "allow"
}
}
}

Rules

Configure agent behavior and constraints via ~/.config/zed/rules.md or .zed/rules.md in the project.

SSH Remote Development

Local machine handles UI, syntax highlighting, and AI. Remote handles LSP, terminal, and tasks. No FUSE, no file sync — Zed runs a headless server instance on the remote.

Connect: Ctrl+Cmd+Shift+O (macOS) / Alt+Ctrl+Shift+O → "Connect New Server"

json
{
"ssh_connections": [
{
"host": "myserver.example.com",
"username": "user",
"port": 22,
"args": ["-i", "~/.ssh/work_key"],
"nickname": "dev-box",
"upload_binary_over_ssh": true
}
]
}

Port forwarding:

json
{
"port_forwards": [
{ "local_port": 8080, "remote_port": 3000, "local_host": "127.0.0.1" }
]
}

Limitations: Cannot open files from remote terminal with zed CLI. Avoid opening very large directories (>100k files).

Tasks

Run commands with access to editor context. Define in ~/.config/zed/tasks.json (global) or .zed/tasks.json (project).

json
[
{
"label": "Run tests",
"command": "cargo test",
"args": ["--", "$ZED_SYMBOL"],
"cwd": "$ZED_WORKTREE_ROOT",
"env": { "RUST_BACKTRACE": "1" },
"use_new_terminal": false,
"allow_concurrent_runs": false,
"reveal": "always",
"hide": "on_success",
"save": "all"
}
]

Available Variables

VariableValue
$ZED_FILEAbsolute path of current file
$ZED_FILENAMEFilename only
$ZED_DIRNAMEDirectory of current file
$ZED_RELATIVE_FILEPath relative to worktree root
$ZED_STEMFilename without extension
$ZED_ROW / $ZED_COLUMNCursor position
$ZED_SELECTED_TEXTCurrent selection
$ZED_SYMBOLSymbol under cursor
$ZED_LANGUAGELanguage of current buffer
$ZED_WORKTREE_ROOTProject root
$ZED_MAIN_GIT_WORKTREEMain git worktree root

Run: task: spawn (task picker), task: rerun (repeat last).

Git-tagged tasks

Tasks with "tags": ["git-command"] appear in Git Graph context menus:

json
{
"label": "Checkout commit",
"command": "git checkout $ZED_GIT_SHA",
"tags": ["git-command"]
}

Hooks

json
{
"label": "Copy .env to worktree",
"command": "cp",
"args": ["$ZED_MAIN_GIT_WORKTREE/.env", "$ZED_WORKTREE_ROOT/.env"],
"hooks": ["create_worktree"],
"reveal": "no_focus",
"hide": "on_success"
}

Debugger

Implements the Debug Adapter Protocol (DAP). Supports: C/C++, Go, JavaScript/TypeScript, PHP, Python, Rust (built-in) + Java, Ruby, Swift (via extensions).

Create .zed/debug.json (or loads .vscode/launch.json as fallback):

json
[
{
"adapter": "CodeLLDB",
"label": "Debug binary",
"request": "launch",
"program": "${ZED_WORKTREE_ROOT}/target/debug/myapp",
"cwd": "$ZED_WORKTREE_ROOT"
}
]

Start: F4 to open process modal, debugger: start.

Settings:

json
{
"debugger": {
"dock": "bottom",
"stepping_granularity": "line",
"save_breakpoints": true,
"inlay_hints": { "show_value_hints": true }
}
}

Git

• Gutter — colored bars for added/modified/deleted lines
• Inline blame — author/commit on current line (editor: toggle git blame inline)
• Diff view — split or unified, editable as multibuffers
• Git panel — stage files, write commit message, push/pull
• AI commit messages — git: generate commit message

Multi-buffer

Search results, diagnostics, and references all open as multi-buffers — excerpts from many files in one view. Edit directly; changes propagate to source files immediately. Save all with the workspace save command.

Open source file from an excerpt: click the divider, or editor: open excerpts.

Extensions

Install via command palette: zed: extensions. Adds language support, themes, debugger adapters, and MCP servers.

Rust, Python, JavaScript/TypeScript, Go, C/C++, JSON, Markdown are built-in — no extension needed.

Language Support

ExtensionAdds
nixNix syntax + nixd/nil LSP
tomlTOML syntax + taplo LSP
htmlHTML + Emmet
vueVue SFCs
svelteSvelte
astroAstro
luaLua + lua-language-server
xmlXML
c-sharpC# via Roslyn LSP
javaJava via jdtls
kotlinKotlin
phpPHP via Intelephense
rubyRuby via Solargraph
elixirElixir via ElixirLS
swiftSwift
dartDart + Flutter
zigZig via ZLS
terraformTerraform/HCL
prismaPrisma schema
latexLaTeX via texlab
sqlSQL syntax
dockerfileDockerfile
scssSCSS/SASS
makeMakefile
logLog file highlighting

Themes

ExtensionStyle
catppuccinSoothing pastel — Latte, Frappé, Macchiato, Mocha
tokyo-nightTokyo Night / Tokyo Storm / Tokyo Moon
one-dark-proAtom-style One Dark
github-themeGitHub Light/Dark
draculaOfficial Dracula
nightfox-themesNeovim Nightfox ports
rose-pineRosé Pine
gruvboxGruvbox dark/light variants

Icon Themes

ExtensionStyle
catppuccin-iconsCatppuccin-colored file icons
material-icon-themeMaterial Design icons

Enable file icons in tabs:

json
{ "tabs": { "file_icons": true } }

Tools

ExtensionWhat it does
git-fireflyGit syntax highlighting (diff, commit messages)
emmetEmmet abbreviation expansion for HTML/CSS
opencodeOpen-source AI coding agent integration

Debugger Extensions

Java, Ruby, and Swift debugger adapters are extension-provided (built-in adapters cover C/C++, Go, JS/TS, Python, Rust).

MCP Extensions

Popular MCP servers installable as extensions: GitHub, Puppeteer, Brave Search, Figma. Browse with the MCP filter on the extensions page.

Collaboration

Real-time collaborative editing via Channels. Multiple users edit the same buffer simultaneously (Google Docs-style). Start from collab: join channel or share a channel link.