Skip to content

How to Configure Zed for a uv Project

uv
This guide assumes a Python project managed with uv. If you haven’t created a project yet, see the project creation tutorial.

Zed ships with built-in support for Python, including Ruff and basedpyright. No extensions are needed. This guide covers the configuration that connects Zed to a uv-managed virtual environment.

Verify the virtual environment

Run uv sync to create the .venv/ directory at your project root. Zed detects .venv automatically using the same library that powers VS Code’s environment detection. Open the project folder in Zed, and the status bar shows the detected Python interpreter.

If Zed picks the wrong interpreter, click the Python version in the status bar to open the toolchain selector and choose the one inside .venv.

Tip

Zed activates the detected virtual environment in every new terminal panel. You can run uv add requests and then python -c "import requests" directly in Zed’s terminal without manual activation.

Configure Ruff for formatting and linting

Ruff runs as a built-in language server in Zed. By default, it formats Python files and reports lint diagnostics with no configuration needed. Ruff reads your project’s pyproject.toml or ruff.toml for rules, so linting stays consistent between the editor and the command line.

To organize imports on save, add this to your Zed settings (Cmd+, on macOS, Ctrl+, on Linux/Windows):

{
  "languages": {
    "Python": {
      "code_actions_on_format": {
        "source.organizeImports.ruff": true
      }
    }
  }
}

To disable format-on-save for Python:

{
  "languages": {
    "Python": {
      "format_on_save": "off"
    }
  }
}

Configure basedpyright for type checking

Basedpyright is the default type-checking language server. It resolves imports from the .venv that Zed detected. No configuration is required for a standard uv project.

To enable stricter type checking, create a pyrightconfig.json at the project root:

{
  "typeCheckingMode": "strict"
}

Zed defaults to standard mode, which is less strict than basedpyright’s own default of recommended.

Switch to ty (optional)

ty is included with Zed and can replace basedpyright as the type checker. To switch:

{
  "languages": {
    "Python": {
      "language_servers": ["ty", "ruff"]
    }
  }
}

Note

ty is in beta. It checks all code by default, including unannotated function bodies that other type checkers skip, so it may surface errors that basedpyright does not. See the ty reference for details.

Add a task for uv run

Zed’s built-in run button executes Python files directly, bypassing uv’s dependency resolution. For scripts that use inline script metadata, add a task to run them with uv run.

Create .zed/tasks.json in your project:

[
  {
    "label": "uv run current file",
    "command": "uv",
    "args": ["run", "$ZED_FILE"],
    "cwd": "$ZED_WORKTREE_ROOT"
  }
]

Run the task from the Command Palette (Cmd+Shift+P / Ctrl+Shift+P) or bind it to a key.

Debug Python code

Press F4 or run debugger: start from the Command Palette. Zed auto-detects Python scripts, modules, and pytest tests and launches them with debugpy. No configuration is needed for basic debugging.

For custom debug configurations, create .zed/debug.json:

[
  {
    "label": "Debug current file",
    "adapter": "Debugpy",
    "program": "$ZED_FILE",
    "request": "launch"
  }
]

Combine all settings

Here is a Zed settings block that combines the configurations above:

{
  "languages": {
    "Python": {
      "code_actions_on_format": {
        "source.organizeImports.ruff": true
      }
    }
  }
}

Zed reads project-level settings from .zed/settings.json (committed to version control) and user-level settings from ~/.config/zed/settings.json. Put project-specific settings in .zed/settings.json so everyone on the team gets the same behavior.

Learn More

Last updated on