# How to configure VS Code for a uv project

{{< callout type="warning" >}}
This guide assumes you have a Python project managed with [uv](https://pydevtools.com/handbook/reference/uv.md). If you haven't created a project yet, see the [project creation tutorial](https://pydevtools.com/handbook/tutorial/create-your-first-python-project.md).
{{< /callout >}}

VS Code needs three things to work well with a [uv](https://pydevtools.com/handbook/reference/uv.md) project: the right Python interpreter, a formatter and linter, and a test runner. This guide covers each.

## Required extensions

Install these extensions from the VS Code marketplace:

- [Python](https://marketplace.visualstudio.com/items?itemName=ms-python.python) (ms-python.python)
- [Ruff](https://marketplace.visualstudio.com/items?itemName=charliermarsh.ruff) (charliermarsh.ruff)

The Python extension handles interpreter selection and test discovery. It also installs the [Python Debugger extension](https://marketplace.visualstudio.com/items?itemName=ms-python.debugpy) (debugpy) automatically, which provides debugging support. The [Ruff](https://pydevtools.com/handbook/reference/ruff.md) extension provides linting and formatting.

## Select the Python interpreter

uv creates a [virtual environment](https://pydevtools.com/handbook/explanation/what-is-a-virtual-environment.md) in `.venv/` at the root of your project. The Python extension detects `.venv` directories automatically, so in most cases the interpreter is selected without any manual configuration.

Run `uv sync` to ensure the virtual environment exists. VS Code should pick up the `.venv` interpreter within a few seconds. If it doesn't, open the Command Palette (`Ctrl+Shift+P` / `Cmd+Shift+P`) and choose **Python: Select Interpreter**, then pick the interpreter inside `.venv`.

> [!TIP]
> If VS Code shows import errors or unresolved modules after adding a dependency with `uv add`, run `uv sync` and then reload the VS Code window (`Ctrl+Shift+P` → **Developer: Reload Window**). The Python language server needs to re-index the environment.

## Configure Ruff for formatting and linting

The Ruff extension replaces both a formatter (like Black) and a linter (like flake8). Add these settings to `.vscode/settings.json`:

```json
{
    "[python]": {
        "editor.defaultFormatter": "charliermarsh.ruff",
        "editor.formatOnSave": true,
        "editor.codeActionsOnSave": {
            "source.organizeImports.ruff": "explicit"
        }
    }
}
```

This formats Python files on save and organizes imports using Ruff. The extension reads your project's `ruff.toml` or `pyproject.toml` settings automatically, so linting rules stay consistent between the editor and the command line.

> [!NOTE]
> If you have the older Black Formatter or isort extensions installed, disable them. The Ruff extension handles both tasks.

## Set up pytest

The Python extension can discover and run [pytest](https://pydevtools.com/handbook/reference/pytest.md) tests from the VS Code sidebar. Add these settings:

```json
{
    "python.testing.pytestEnabled": true,
    "python.testing.unittestEnabled": false,
    "python.testing.pytestArgs": ["tests"]
}
```

After saving, open the Testing sidebar (beaker icon) and click **Refresh Tests**. VS Code will discover tests in your `tests/` directory and let you run or debug them individually.

If pytest is a development dependency in your project (`uv add --dev pytest`), VS Code will find it in the `.venv` automatically.

## Complete settings file

Here is a `.vscode/settings.json` that combines all the configurations above:

```json
{
    "python.testing.pytestEnabled": true,
    "python.testing.unittestEnabled": false,
    "python.testing.pytestArgs": ["tests"],
    "[python]": {
        "editor.defaultFormatter": "charliermarsh.ruff",
        "editor.formatOnSave": true,
        "editor.codeActionsOnSave": {
            "source.organizeImports.ruff": "explicit"
        }
    }
}
```

Commit this file to version control so everyone on the team gets the same formatter and test settings. Interpreter selection does not need to be checked in because VS Code auto-detects the `.venv` directory that uv creates.

## Running Python files

The play button (**Run Python File**) in VS Code runs your file with the selected interpreter directly. It does not wrap the command in `uv run`, so it bypasses uv's dependency resolution for [inline script metadata](https://packaging.python.org/en/latest/specifications/inline-script-metadata/). For standalone scripts that declare their own dependencies with inline metadata, run them from the integrated terminal with `uv run script.py` instead of the play button.

For project code where dependencies are already installed in `.venv` via `uv sync`, the play button works fine.

## Jupyter notebooks

To use Jupyter notebooks in VS Code with a uv project, add `ipykernel` as a development dependency:

```bash
uv add --dev ipykernel
```

Open a `.ipynb` file and VS Code will prompt you to select a kernel. Choose the Python interpreter from your `.venv` directory. If no kernel appears, run `uv sync` first to ensure `ipykernel` is installed in the environment.

For more details, see [How to run a Jupyter notebook with uv](https://pydevtools.com/handbook/how-to/jupyter-notebook-with-uv.md).

## Type checking with ty

[ty](https://pydevtools.com/handbook/reference/ty.md) is Astral's type checker for Python, built by the same team behind uv and Ruff. The [ty VS Code extension](https://marketplace.visualstudio.com/items?itemName=astral-sh.ty) (`astral-sh.ty`) provides type error diagnostics directly in the editor.

> [!NOTE]
> ty is in beta. Expect rough edges compared to mature type checkers like [mypy](https://pydevtools.com/handbook/reference/mypy.md) or [pyright](https://pydevtools.com/handbook/reference/pyright.md).

## Debugging

With the [Python Debugger extension](https://marketplace.visualstudio.com/items?itemName=ms-python.debugpy) installed, open a Python file and run **Python Debugger: Debug Python File** from the Command Palette (`Cmd+Shift+P` / `Ctrl+Shift+P`). For more control, create a `.vscode/launch.json`:

```json
{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Python: Current File",
            "type": "debugpy",
            "request": "launch",
            "program": "${file}",
            "console": "integratedTerminal"
        },
        {
            "name": "Python: Module",
            "type": "debugpy",
            "request": "launch",
            "module": "your_package",
            "console": "integratedTerminal"
        }
    ]
}
```

Replace `your_package` with your project's package name. The debugger uses the interpreter from `.venv`, so it has access to all dependencies installed by uv.

> [!TIP]
> To debug a single pytest test, right-click the gutter icon next to the test in the editor and choose **Debug Test**. You can also use the bug icon in the Test Explorer sidebar.

## Troubleshooting

"Import could not be resolved" warnings: Run `uv sync` to install all dependencies, then reload the VS Code window.

Wrong Python version: Check that `uv python pin` matches what VS Code shows in the status bar. If they differ, re-select the interpreter from the Command Palette.

Ruff settings not applied: The Ruff extension reads from `pyproject.toml` or `ruff.toml` in your project root. Run `uv run ruff check .` in the terminal to verify the rules match what the extension reports.

uv workspaces (monorepos): Pylance does not fully understand uv workspace structures. Imports between workspace members may show false "unresolved import" warnings. As a workaround, add import paths to `python.analysis.extraPaths` in your workspace settings, or open each workspace member as a separate VS Code window.

## Learn More

- [VS Code Python documentation](https://code.visualstudio.com/docs/languages/python)
- [Ruff VS Code extension](https://github.com/astral-sh/ruff-vscode)
- [uv reference](https://pydevtools.com/handbook/reference/uv.md)
- [How to install uv](https://pydevtools.com/handbook/how-to/how-to-install-uv.md)
- [pytest tutorial](https://pydevtools.com/handbook/tutorial/setting-up-testing-with-pytest-and-uv.md)
