← Back to DevBytes

Zed Project Management: Complete Guide

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:

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:

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:

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:

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.

— Ad —

Google AdSense will appear here after approval

← Back to all articles