Skip to content

How to configure Cursor for Ruff

Cursor is a fork of VS Code, so the Ruff extension installs and behaves the same way. The one Cursor-specific difference is the extension source: Cursor uses the Open VSX Registry instead of the VS Code Marketplace. The extension ID (charliermarsh.ruff) is the same.

Tip

This guide focuses on Ruff configuration. If you haven’t set up your Python interpreter in Cursor yet, start with How to configure Cursor for a uv project.

This guide assumes you have Cursor installed and a Python project with a virtual environment. Use uv to add Ruff as a project dependency before proceeding:

uv add --dev ruff

The --dev flag marks Ruff as a development dependencyA package needed during development (testing, linting, formatting) that is not shipped to users of your project. Installed with the –dev flag. , keeping it out of production installs. uv updates pyproject.toml and uv.lock, then installs Ruff in .venv.

Install the Ruff extension

Open Cursor’s extension panel (Ctrl+Shift+X / Cmd+Shift+X) and search for Ruff. Install the extension published by Astral Software (ID: charliermarsh.ruff).

If the Black Formatter extension or the isort extension is installed, disable or uninstall them. Ruff covers both tasks; running two formatters on save causes conflicts.

Configure format-on-save

Create or open .vscode/settings.json at the project root and add:

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

With "explicit", source.fixAll.ruff applies Ruff’s auto-fixable lint rules on manual saves; source.organizeImports.ruff sorts imports. These actions do not run on Auto Save. Use "always" instead if they should also run on supported Auto Save events. The .ruff suffix scopes each action to this extension only, so adding another formatter later won’t interfere.

Rule selection and other linting settings live in pyproject.toml, not in this file. Commit .vscode/settings.json so everyone on the project gets the same formatter behavior.

Use the project’s Ruff, not the bundled one

The extension defaults to importStrategy: "fromEnvironment", which looks for Ruff in the active Python environment before falling back to the binary bundled with the extension. With Ruff installed in the selected .venv, the editor and uv run ruff use the project’s version.

Select the project’s .venv with Python: Select Interpreter so the extension searches the intended environment. Installing Ruff as a project dependency alone does not select that environment.

To confirm which Ruff the editor loaded, open the Command Palette (Ctrl+Shift+P / Cmd+Shift+P) and run Ruff: Show server logs. The output channel shows the path to the Ruff executable on startup. A path under .venv/ confirms the editor is using the project’s version.

Configure project-level rules

The extension discovers pyproject.toml (under [tool.ruff]), ruff.toml, or .ruff.toml for each file. Editor configuration is not needed for rule selection. Add rules to pyproject.toml:

pyproject.toml
[tool.ruff.lint]
extend-select = ["I", "UP", "RET", "SIM"]

Keep rule settings in this file to share them with the editor and CI. Editor-level Ruff settings can override project configuration; use "ruff.configurationPreference": "filesystemFirst" in .vscode/settings.json if project configuration should take precedence. uv run executes the command inside the project’s virtual environment, ensuring all dependencies are installed first. For a curated starter set, see How to configure recommended Ruff defaults.

Troubleshoot common issues

Extension not formatting on save. Open Settings and confirm charliermarsh.ruff is the default Python formatter. If another formatter extension is active, it may have overridden the setting. Disable any Black Formatter or isort extensions, then reload the window.

Editor and terminal enforce different rules. Run Ruff: Show server logs to check which binary the editor loaded. If it uses the bundled binary, install Ruff in the project, select its .venv interpreter, and run Ruff: Restart Server. Also check editor-level configuration overrides.

Ruff not finding your config. Ruff discovers configuration for each file, including nested pyproject.toml, ruff.toml, and .ruff.toml files. Check for a closer configuration file or an editor-level ruff.configuration setting. Nested configuration files do not automatically merge with parent configuration; use Ruff’s extend setting when inheritance is intended.

Import sorting not working. Confirm source.organizeImports.ruff is configured and ruff.organizeImports is not set to false. Enable the I rule category in the project configuration so command-line linting also checks import order; the editor’s organize-imports action can run independently of that selection.

Last updated on