Introduction to Zed Project Management
Zed is a next-generation, high-performance code editor built in Rust by the team behind Atom. While much of the spotlight has fallen on its speed and collaborative features, Zed also ships with a robust set of project management capabilities that make it a serious contender for daily development workflows. Understanding how to leverage these features can dramatically improve your productivity, especially when juggling multiple repositories, monorepos, or collaborative sessions.
This guide walks through everything you need to know about managing projects in Zed — from opening your first workspace to advanced configuration, collaboration, and automation.
What Is Zed Project Management?
At its core, Zed treats a "project" as a workspace bound to one or more directories on your filesystem. Unlike traditional editors that conflate projects with saved files, Zed's project model is directory-centric and configuration-driven. Each project carries its own settings, task definitions, language server configurations, and collaboration state.
Key components of Zed's project system include:
- Workspaces — container windows that hold one or more project directories.
- Project settings — local JSON configuration scoped to a specific project.
- Tasks — reusable commands defined per project for build, test, and run workflows.
- Collaboration — real-time shared editing sessions tied to a project.
- Multi-project panes — the ability to open several projects side by side in a single window.
Why Project Management in Zed Matters
Modern development rarely involves a single isolated codebase. You might work on a frontend app, a backend service, shared libraries, infrastructure code, and documentation — sometimes all in the same session. Zed's project management features address several pain points:
- Context switching — quickly jump between projects without losing your editor state, open files, or terminal sessions.
- Reproducible environments — project-scoped settings ensure every contributor gets the same editor behavior.
- Streamlined collaboration — share an entire project with teammates in seconds, including tasks and configurations.
- Performance at scale — Zed's Rust-based architecture handles large monorepos without the sluggishness common in Electron-based editors.
Getting Started: Opening and Creating Projects
Opening a Project from the Command Line
The fastest way to open a project in Zed is from the terminal. Navigate to your project directory and launch Zed:
cd ~/projects/my-web-app
zed .
This opens the current directory as a project in a new Zed window. You can also open multiple directories at once, which is useful for polyrepo setups:
zed ~/projects/frontend ~/projects/backend ~/projects/shared-lib
All three directories will appear in the project panel, and Zed will treat them as a single workspace.
Opening Projects from the GUI
If you prefer the graphical approach, use Cmd+O on macOS (or Ctrl+O on Linux) to open the file picker. Select a folder and Zed will load it as a project. You can add additional folders to an existing workspace via the command palette:
Cmd+Shift+P -> "Project: Add Folder to Workspace"
The Project Panel
Once a project is open, the project panel on the left displays your directory tree. You can toggle it with Cmd+B. The panel supports standard operations: creating files, renaming, deleting, and dragging items. Files opened from any project directory appear as tabs in the editor pane, and Zed keeps track of which project each file belongs to.
Project Configuration
The settings.json Hierarchy
Zed uses a layered settings system. Global user settings live in ~/.config/zed/settings.json, while project-specific settings live in a .zed directory at the root of your project. Project settings override user settings, allowing you to customize behavior per codebase.
Create a project settings file at .zed/settings.json in your project root:
{
"format_on_save": "on",
"tab_size": 2,
"preferred_line_length": 100,
"soft_wrap": "preferred_line_length",
"languages": {
"Python": {
"tab_size": 4,
"formatter": {
"language_server": {
"name": "ruff"
}
}
},
"Rust": {
"tab_size": 4,
"formatter": "language_server"
}
},
"lsp": {
"rust-analyzer": {
"initialization_options": {
"check": {
"command": "clippy"
}
}
}
}
}
This configuration ensures that anyone opening the project gets consistent formatting, language server behavior, and linting rules. Committing .zed/settings.json to version control is a best practice for team alignment.
Environment Variables
Zed allows you to define environment variables scoped to a project. This is particularly useful for setting NODE_ENV, DATABASE_URL, or other runtime configuration without polluting your shell profile. Add an env key to your project settings:
{
"env": {
"NODE_ENV": "development",
"DATABASE_URL": "postgres://localhost:5432/myapp_dev",
"LOG_LEVEL": "debug"
}
}
These variables are available to tasks, integrated terminals, and language servers launched within the project.
Working with Tasks
Defining Project Tasks
Tasks are one of Zed's most powerful project management features. They let you define reusable commands — builds, tests, scripts, dev servers — that run with a single keystroke. Tasks are defined in .zed/tasks.json:
[
{
"label": "dev server",
"command": "npm run dev",
"env": {
"PORT": "3000"
},
"use_new_terminal": true,
"allow_concurrent_runs": false,
"reveal": "always"
},
{
"label": "run tests",
"command": "npm test -- --watch",
"use_new_terminal": true,
"allow_concurrent_runs": false
},
{
"label": "build",
"command": "npm run build",
"use_new_terminal": true,
"reveal": "always"
},
{
"label": "lint",
"command": "npx eslint . --fix",
"use_new_terminal": true
}
]
Running Tasks
Once defined, tasks are accessible via the task runner. Open it with Cmd+Shift+T (or Ctrl+Shift+T on Linux). You will see a list of available tasks, and selecting one spawns a terminal pane that executes the command. Tasks can also be bound to keyboard shortcuts in your keymap file.
For a Rust project, a typical tasks file might look like this:
[
{
"label": "cargo run",
"command": "cargo run",
"use_new_terminal": true,
"reveal": "always"
},
{
"label": "cargo test",
"command": "cargo test",
"use_new_terminal": true
},
{
"label": "cargo clippy",
"command": "cargo clippy -- -D warnings",
"use_new_terminal": true
},
{
"label": "cargo watch",
"command": "cargo watch -x run",
"use_new_terminal": true,
"allow_concurrent_runs": false
}
]
Task Variables
Zed supports variable substitution in task definitions, allowing you to reference the current file, project path, or symbol under the cursor. This makes tasks context-aware:
[
{
"label": "run current file",
"command": "python3 $ZED_FILE",
"use_new_terminal": true
},
{
"label": "test current file",
"command": "pytest $ZED_FILE -v",
"use_new_terminal": true
},
{
"label": "go to symbol doc",
"command": "open https://pkg.go.dev/search?q=$ZED_SYMBOL",
"use_new_terminal": false
}
]
The available variables include $ZED_FILE (current file path), $ZED_FILENAME (file name only), $ZED_DIRNAME (containing directory), $ZED_SYMBOL (symbol under cursor), and $ZED_ROW / $ZED_COLUMN (cursor position).
Multi-Project Workflows
Adding Multiple Projects to a Workspace
For developers working across interconnected services, Zed's multi-project support is invaluable. You can add several top-level directories to a single workspace, and each retains its own project settings while sharing the editor window. Use the command palette:
Cmd+Shift+P -> "Project: Add Folder to Workspace"
Alternatively, launch Zed with multiple paths from the CLI:
zed ~/work/api-gateway ~/work/auth-service ~/work/web-client ~/work/infra
Each folder appears as a separate root in the project panel, and Zed intelligently manages language servers per project. This means your TypeScript language server runs for the web client while your Go language server runs for the API gateway — all in one window.
Searching Across Projects
With multiple projects loaded, global search becomes especially powerful. Press Cmd+Shift+F to open the project-wide search panel. By default, it searches all loaded project directories. You can scope searches using the filter input:
# Exclude node_modules and dist directories
!**/node_modules/** !**/dist/**
For more targeted searches, use regex mode and file-type filters to narrow results across all projects simultaneously.
Collaboration and Project Sharing
Starting a Collaboration Session
Zed's collaboration features are tightly integrated with its project model. To share a project with teammates, click the collaboration icon in the status bar or use the command palette:
Cmd+Shift+P -> "Collaboration: Share Project"
Zed generates a shareable link. When a teammate opens it, they join your project session with full access to the file tree, open buffers, and tasks. Everyone sees each other's cursors, selections, and edits in real time.
Collaboration Best Practices
When collaborating on a project in Zed, keep the following in mind:
- Ensure all participants have the project's language tooling installed locally for accurate LSP features.
- Use project-scoped settings (
.zed/settings.json) so formatting and linting behave identically for everyone. - Define shared tasks so teammates can run the same build and test commands without manual setup.
- Communicate which files you are editing to avoid conflicting simultaneous edits in the same region.
Version Control Integration
Git Status in the Project Panel
Zed automatically detects Git repositories within your projects and displays file status indicators in the project panel. Modified files show an "M" badge, untracked files show a "U", and staged files show an "S". This gives you at-a-glance awareness of your working tree state.
Committing and Diffing
While Zed's Git integration is still evolving, you can view diffs by clicking on modified files in the project panel. For committing, the integrated terminal is your primary tool. A practical workflow combines Zed's editor with Git CLI commands:
# In Zed's integrated terminal (Ctrl+`)
git add -A
git commit -m "feat: add user authentication flow"
git push origin feature/auth
You can also define a Git task for common operations:
[
{
"label": "git: status",
"command": "git status",
"use_new_terminal": true
},
{
"label": "git: diff",
"command": "git diff",
"use_new_terminal": true
},
{
"label": "git: pull rebase",
"command": "git pull --rebase origin main",
"use_new_terminal": true
}
]
Best Practices for Zed Project Management
1. Commit Project Configuration
Always commit your .zed/settings.json and .zed/tasks.json files to version control. This ensures every team member benefits from consistent formatting, language server settings, and task definitions. Use a .gitignore entry only for personal overrides:
# .gitignore
.zed/settings.local.json
.zed/tasks.local.json
Zed will load *.local.json variants and merge them with the committed versions, giving developers a safe space for personal preferences.
2. Structure Tasks Hierarchically
As your task list grows, use clear naming conventions with prefixes like build:, test:, deploy:, or db:. This keeps the task runner organized and makes it easy to find what you need:
[
{
"label": "db: migrate",
"command": "python manage.py migrate",
"use_new_terminal": true
},
{
"label": "db: make migrations",
"command": "python manage.py makemigrations",
"use_new_terminal": true
},
{
"label": "db: shell",
"command": "python manage.py shell",
"use_new_terminal": true
},
{
"label": "test: unit",
"command": "python manage.py test --verbosity=2",
"use_new_terminal": true
},
{
"label": "test: e2e",
"command": "pytest tests/e2e/ -v",
"use_new_terminal": true
}
]
3. Leverage Snippets for Project-Specific Code
Zed supports custom snippets defined in .zed/snippets/. For project-specific boilerplate, create snippet files that match your codebase patterns:
// .zed/snippets/react.json
{
"React Component": {
"prefix": "rcomp",
"body": [
"import React from 'react';",
"",
"interface ${1:ComponentName}Props {",
" ${2}",
"}",
"",
"export function ${1:ComponentName}({ ${2} }: ${1:ComponentName}Props) {",
" return (",
" ",
" $0",
" ",
" );",
"}"
]
},
"React Hook": {
"prefix": "rhook",
"body": [
"import { useState, useEffect } from 'react';",
"",
"export function ${1:useCustomHook}() {",
" const [state, setState] = useState(${2:null});",
"",
" useEffect(() => {",
" $0",
" }, []);",
"",
" return state;",
"}"
]
}
}
4. Use Workspaces for Related Projects
Instead of opening separate Zed windows for related repositories, combine them into a single workspace. This reduces window clutter, enables cross-project search, and lets you define tasks that span multiple services. For example, a full-stack workspace might include your frontend, backend, shared types, and infrastructure code.
5. Optimize Language Server Configuration
Different projects often need different LSP configurations. Use the lsp key in project settings to fine-tune behavior. For a TypeScript project using a monorepo setup:
{
"lsp": {
"typescript-language-server": {
"initialization_options": {
"preferences": {
"importModuleSpecifierPreference": "relative",
"quotePreference": "single"
}
}
},
"eslint": {
"initialization_options": {
"lint": true,
"format": true
}
}
}
}
6. Keep Performance in Check
While Zed is fast, loading enormous directories can still impact responsiveness. Use file_scan_exclusions in your project settings to skip irrelevant directories:
{
"file_scan_exclusions": [
"**/.git",
"**/node_modules",
"**/dist",
"**/build",
"**/.next",
"**/coverage",
"**/vendor",
"**/.cache"
]
}
This prevents Zed from indexing directories that would only slow down file navigation and search.
Advanced: Project Templates and Automation
Scripting Project Creation
If you frequently create new projects with similar structures, automate the process with a shell script that scaffolds both the codebase and Zed configuration:
#!/bin/bash
# create-project.sh - Scaffold a new Node.js project with Zed config
PROJECT_NAME=$1
BASE_DIR="${2:-~/projects}"
if [ -z "$PROJECT_NAME" ]; then
echo "Usage: create-project.sh [base-dir]"
exit 1
fi
PROJECT_DIR="$BASE_DIR/$PROJECT_NAME"
mkdir -p "$PROJECT_DIR"
cd "$PROJECT_DIR" || exit 1
# Initialize Node project
npm init -y
# Create Zed configuration
mkdir -p .zed/snippets
cat > .zed/settings.json << 'EOF'
{
"format_on_save": "on",
"tab_size": 2,
"preferred_line_length": 100,
"languages": {
"JavaScript": {
"formatter": "prettier"
},
"TypeScript": {
"formatter": "prettier"
}
}
}
EOF
cat > .zed/tasks.json << 'EOF'
[
{
"label": "dev",
"command": "node src/index.js",
"use_new_terminal": true,
"reveal": "always"
},
{
"label": "test",
"command": "node --test",
"use_new_terminal": true
}
]
EOF
# Create source structure
mkdir -p src tests
cat > src/index.js << 'EOF'
console.log("Hello from ${PROJECT_NAME}!");
EOF
echo "Project created at $PROJECT_DIR"
echo "Open with: zed $PROJECT_DIR"
Make the script executable and run it:
chmod +x create-project.sh
./create-project.sh my-new-service
zed ~/projects/my-new-service
Integrating with Make and Just
If your project already uses Makefile or justfile, you can bridge those tools into Zed tasks for a unified experience:
[
{
"label": "make: all",
"command": "make all",
"use_new_terminal": true,
"reveal": "always"
},
{
"label": "make: clean",
"command": "make clean",
"use_new_terminal": true
},
{
"label": "just: test",
"command": "just test",
"use_new_terminal": true
},
{
"label": "just: deploy",
"command": "just deploy",
"use_new_terminal": true,
"reveal": "always"
}
]
Keyboard Shortcuts for Project Navigation
Efficient project management in Zed relies on muscle memory. Here are the essential shortcuts:
Cmd+B— Toggle the project panelCmd+P— Quick file open (fuzzy search within project)Cmd+Shift+P— Open the command paletteCmd+Shift+F— Project-wide searchCmd+Shift+T— Open the task runnerCtrl+`— Toggle the integrated terminalCmd+Shift+E— Focus the project panelCmd+K Cmd+P— Switch between open projects/workspaces
You can customize any of these in your keymap file at ~/.config/zed/keymap.json:
[
{
"context": "Workspace",
"bindings": {
"cmd-shift-a": "project_panel::ToggleFocus",
"cmd-shift-r": "task::Spawn"
}
}
]
Conclusion
Zed's project management system is deceptively powerful. What starts as a simple directory-based workspace evolves into a rich environment with per-project settings, reusable tasks, multi-project support, real-time collaboration, and deep language server integration. By committing your .zed configuration to version control, structuring tasks thoughtfully, leveraging snippets, and optimizing performance with file exclusions, you create a reproducible and efficient development environment that benefits both you and your team. As Zed continues to evolve, its project management capabilities will only grow richer — investing time in mastering them now will pay dividends as the editor matures into a primary tool for your daily workflow.