Skip to main content

Add Pyrefly to your IDE

Pyrefly seamlessly integrates into IDEs with our VSCode and OpenVSX extensions. For other editors like vim/emacs, see other editors.

To see what features are supported by the IDE extension, see the Supported Features page.

Quick start

  1. Install the Pyrefly extension from the VS Code Marketplace or Open VSX.
  2. Open any Python file and the extension will activate automatically.
tip

Not seeing inlay hints in VS Code? Try setting editor.inlayHints.enabled to true in your VS Code settings.

tip

Want type error squiggles to show up in your editor by default? Run pyrefly init. It adds a [tool.pyrefly] section to an existing pyproject.toml, or creates a new pyrefly.toml if no pyproject.toml is present. You can also set python.pyrefly.typeCheckingMode to "default" or "strict" in your editor settings.

Customization

By default, Pyrefly should work in the IDE with no configuration necessary. But to ensure your project is set up properly, see configurations.

VSCode Extension Settings

The following configuration options are IDE-specific and exposed as VSCode settings:

python.pyrefly.typeCheckingMode

Type: enum (auto, off, basic, legacy, default, strict)   Default: "auto"

Controls Pyrefly's behavior for files not covered by a pyrefly.toml or [tool.pyrefly] section. Those configurations always take precedence over this setting.

  • auto (default): auto-detects a nearby mypy.ini / pyrightconfig.json (or [tool.mypy] / [tool.pyright] in pyproject.toml) and automatically migrates it. Falls back to the basic preset if nothing is found.
  • off: silences every error kind. Useful for editor users who only want IDE features (hover, go-to-def) without diagnostics.
  • basic: minimal checking. Only high-confidence errors fire; everything else is silenced.
  • legacy: looser preset for codebases migrating from mypy. Unlike auto, this is just the bare preset with no migration of any nearby mypy/pyright config.
  • default: Pyrefly's default behavior.
  • strict: additional error kinds on top of default for stricter checking.

The non-auto values force a specific preset and skip auto-detection.

python.pyrefly.disableTypeErrors

Type: boolean   Default: false

Workspace kill switch for Pyrefly type-error diagnostics. When true, all errors are suppressed for files in this workspace, regardless of pyrefly.toml settings or preset. The status bar shows Pyrefly (Errors Off) and the hover explains the source. When false (the default), Pyrefly defers to the project's pyrefly.toml and any in-config disable-type-errors-in-ide flag. The project's committed config is authoritative.

There is no override that bypasses an in-config disable. If a project ships with disable-type-errors-in-ide = true and you want to see errors locally, remove the flag from your pyrefly.toml.

python.pyrefly.displayTypeErrors (deprecated)

Type: enum (default, force-on, force-off, error-missing-imports)   Default: "default"

warning

Replaced by typeCheckingMode and disableTypeErrors. This setting still works for backwards compatibility but new configurations should use the replacements. When both legacy and new settings are present, the new settings take precedence.

Legacy mapping onto the new model:

  • force-on -> typeCheckingMode = "default". No effect on disableTypeErrors.
  • force-off -> disableTypeErrors = true (workspace kill switch). No effect on Pyrefly's behavior for files without a Pyrefly configuration.
  • default resets both new settings to their unset values (typeCheckingMode = "auto", disableTypeErrors = false). Use it to clear a previous force-on / force-off setting.
  • error-missing-imports was removed in v0.64.0 and now behaves identically to default.

python.pyrefly.diagnosticMode

Type: enum (openFilesOnly, workspace)   Default: "openFilesOnly"

Controls the scope of Pyrefly's diagnostic analysis. When set to 'openFilesOnly', diagnostics are only computed for files currently open in the editor. When set to 'workspace', Pyrefly publishes diagnostics for all files in a project once any file from that project is opened. Projects are identified through pyrefly config files (pyrefly.toml or pyproject.toml with [tool.pyrefly]) discovered by the normal upward config search. Files not covered by any explicit pyrefly config are not included.

python.pyrefly.disableLanguageServices

Type: boolean   Default: false

If true, Pyrefly will not provide IDE services like completions, hover, definition, etc. Type errors are controlled separately via disableTypeErrors and typeCheckingMode. Set to true to keep type errors from Pyrefly unchanged but use VSCode's Python extension for everything else.

python.pyrefly.disabledLanguageServices

Type: object   Default: {}

Granular toggle to disable individual language services. Set a service to true to disable it. For example, if you want go-to definition but not find-references.

Available services: hover, documentSymbol, workspaceSymbol, inlayHint, completion, codeAction, definition, declaration, typeDefinition, references, documentHighlight, rename, codeLens, semanticTokens, signatureHelp, implementation, callHierarchy.

python.pyrefly.configPath

Type: string   Default: ""

Path to a pyrefly.toml or pyproject.toml configuration file. When set, the LSP will use this config for all files in your workspace instead of the default Pyrefly config-finding logic wherever possible.

python.pyrefly.streamDiagnostics

Type: boolean   Default: true

If true, Pyrefly streams diagnostics as they become available during recheck, providing incremental feedback. Set to false to only publish diagnostics after the full recheck completes.

python.pyrefly.syncNotebooks

Type: boolean   Default: true

If true, Pyrefly will sync notebook documents with the language server. Set to false to disable notebook support.

python.pyrefly.runnableCodeLens

Type: boolean   Default: false

Enable Pyrefly's Run/Test CodeLens actions for Python files.

Type: boolean   Default: true

Controls whether hover tooltips include "Go to definition" and "Go to type definition" navigation links. Set to false for cleaner tooltips with only type information.

python.analysis.completeFunctionParens

Type: boolean   Default: false

Automatically insert parentheses when completing a function or method.

pyrefly.lspPath

Type: string   Default: ""

If your platform is not supported, you can build pyrefly from source and specify the binary path with this setting.

pyrefly.lspArguments

Type: array of strings   Default: ["lsp"]

Additional arguments passed to the binary at pyrefly.lspPath.

pyrefly.trace.server

Type: enum (off, verbose)   Default: "off"

Set to 'verbose' to enable LSP trace output in the console. Useful for debugging LSP communication issues.

pyrefly.commentFoldingRanges

Type: boolean   Default: false

Controls whether comment section folding ranges are included in the editor. When true, comments following the pattern # Section Name ---- (with 4+ trailing dashes) create collapsible regions, similar to R's code section convention.

python.defaultInterpreterPath

Type: string

This is a setting from the Python extension. If the Python extension is installed, selecting an interpreter will override the interpreter and settings Pyrefly uses to type check your project, even if one is specified in your Pyrefly configuration. python.defaultInterpreterPath will override the default interpreter selected by VSCode for your workspace.

LSP initializationOptions

When used with non-VSCode editors, the options above can also be configured by sending them via initializationOptions in the LSP initialization request.

Below is an example of a value that can be passed for initializationOptions:

{
"pythonPath": "/usr/bin/python3",
"commentFoldingRanges": true,
"pyrefly": {
"typeCheckingMode": "auto",
"disableTypeErrors": false,
"displayTypeErrors": "default",
"typeErrorDisplayStatusVersion": "v2",
"disableLanguageServices": false,
"extraPaths": ["/path/to/extra/modules"],
"analysis": {
"diagnosticMode": "workspace",
"importFormat": "absolute",
"inlayHints": {
"callArgumentNames": "off",
"functionReturnTypes": true,
"pytestParameters": false,
"variableTypes": true
},
"showHoverGoToLinks": true
},
"disabledLanguageServices": {
"hover": false,
"documentSymbol": false,
"workspaceSymbol": false,
"inlayHint": false,
"completion": false,
"codeAction": false,
"definition": false,
"declaration": false,
"typeDefinition": false,
"references": false,
"documentHighlight": false,
"rename": false,
"codeLens": false,
"semanticTokens": false,
"signatureHelp": false,
"implementation": false,
"callHierarchy": false
}
}
}

Custom request: pyrefly/textDocument/typeErrorDisplayStatus

Third-party integrators can ask the server about Pyrefly's current type-checking state for a given file via the custom request pyrefly/textDocument/typeErrorDisplayStatus. The wire shape is versioned via initializationOptions.pyrefly.typeErrorDisplayStatusVersion:

  • "v1" (legacy default): the server returns a bare JSON string from the original TypeErrorDisplayStatus enum (enabled-in-config-file, disabled-in-ide-config, no-config-file, etc.). Every historical client can decode this shape. A missing or unspecified version also resolves to v1 so older clients keep working unchanged.
  • "v2": the server returns an object:
    {
    "version": "v2",
    "label": "Basic" | "Legacy" | "Default" | "Errors Off" | null,
    "tooltip": "markdown string",
    "docsUrl": "https://pyrefly.org/..."
    }
    Basic / Legacy / Default are emitted when Pyrefly synthesized a config (no pyrefly.toml was found) and tell the user which preset is active. Errors Off is emitted whenever diagnostics are suppressed, either by the workspace disableTypeErrors kill switch or by in-config disable-type-errors-in-ide. null is emitted for everything else (project has a real pyrefly.toml, or the user explicitly set typeCheckingMode). In that case the client should render plain Pyrefly with no parenthetical. The Pyrefly VS Code extension uses V2 to render the status-bar parenthetical (e.g. Pyrefly (Basic) or Pyrefly (Errors Off)).

Clients should dispatch on response shape (typeof resp === 'string' for V1, resp.version for V2+) so they can transparently support servers older than the version they declared.

If a client opts into a version the server doesn't recognize (e.g. a future v3 against a server that only knows up to v2), the server clamps to the latest version it can produce (v2 in that example). The richer shape is the closest the server can offer to what the client asked for. A fallback to v1 would silently strip features the client explicitly requested. Clients should still defensively dispatch on resp.version so they can recognize when the server has clamped them down.

Issues?

If you experience issues with the Pyrefly extension, please create an issue on github.

Other Editors

Support for other editors is community-driven. If you would like to set this up, please contribute.

Antigravity, Windsurf, Cursor and Kiro

You can use Pyrefly in your favorite AI editor that supports OpenVSX extensions. Search for "Pyrefly" in the extension marketplace and install it. Similar to VSCode, Pyrefly will automatically activate when you open a Python file.

To avoid conflicts, you should disable other Python language servers by either setting "Language Server: None" in the extension settings or by disabling the Pyright or BasedPyright extensions.

Jetbrains / Pycharm

PyCharm users can enable native Pyrefly support in the settings:

  1. Go to Python | Tools | Pyrefly in the Settings dialog.

  2. Select the Enable checkbox.

  3. In the Execution mode setting, select how PyCharm should search for the executable:

    Interpreter mode: PyCharm searches for an executable installed in your interpreter. To install the Pyrefly package for the selected interpreter, click Install Pyrefly.

    Path mode: PyCharm searches for an executable in $PATH. If the executable is not found, you can specify the path by clicking the Browse... icon.

  4. Select which options should be enabled.

For more information, refer to PyCharm documentation.

Neovim

Pyrefly supports native Neovim support through lspconfig on Neovim 0.11+. Install and setup Pyrefly using the settings below.

The recommended way to set up Pyrefly in Neovim 0.11+ is:

  1. Install or update the neovim/nvim-lspconfig, mason-org/mason.nvim, and mason-org/mason-lspconfig.nvim plugins with your plugin manager of choice.
  2. Add the following to your Neovim init.lua:
require("mason").setup()
require("mason-lspconfig").setup()
  1. In Neovim, run :MasonInstall pyrefly or add pyrefly to your ensure_installed options:
require("mason-lspconfig").setup {
ensure_installed = { "pyrefly" },
}
Alternative setups and configurations

While the above section describes the fastest way to set up Pyrefly, you may already have a setup or prefer to use other approaches for your lspconfig. Below we describe alternatives to both Pyrefly installation and configuration.

note

We don't provide instructions for setting up Neovim with versions prior to Neovim 0.11, though Pyrefly can work with them through neovim/nvim-lspconfig.

Install Pyrefly for Neovim

There are two methods we currently support for installing Pyrefly for Neovim:

  1. (recommended) Install the mason-org/mason.nvim plugin, which handles installing language services and configuring them easily.
  2. Use a system installation.
mason.nvim

mason.nvim is our recommended approach, since it makes Pyrefly and other language servers, linters, and utilities easily available to Neovim.

note

Installing a binary with Mason will take precedence over other system installations. It might be worth using system installations (including installations in virtual environments) if you need to switch between different versions of Pyrefly for different projects.

Install Mason using your Neovim plugin manager of choice, and make sure you call its setup function to make it available.

To install Pyrefly, run :MasonInstall pyrefly in Neovim, and it will be installed! You can install a specific version of Pyrefly with :MasonInstall pyrefly@<version>, and manage Mason installations (including per-language-server-specific settings!) with :Mason.

System Installations

Pyrefly can also work with Neovim's lspconfig when using a system installation. This will work as long as the Pyrefly binary you want to use is available on your $PATH, which you can check by making sure commands like pyrefly --help succeed. If an installation is available on your $PATH, continue on to configure below.

To install Pyrefly, you can use the package manager of your choice. We support uv, pip, Cargo, and anything else that can interface with PyPI (see Installation for more info).

note

If you're installing Pyrefly into a virtual environment, please be aware that Pyrefly will only work within Neovim if the virtual environment is activated when you start Neovim.

Before moving on, double check that you can access Pyrefly on your $PATH. If you can, then continue with configure.

If Pyrefly is not available on your $PATH, you can try the following:

  • If you're using a virtual environment, try source .venv/bin/activate to ensure your venv is running, then see if pyrefly is available.
  • If you're using uv, you can ensure uv-installed tools are available on your path by running uv tool update-shell.
  • Configure lspconfig to use a specific executable/command by updating your Pyrefly-specific lspconfig settings. To do this, override the cmd configuration option with your command in the configuration section below.
Configure Pyrefly for Neovim

This section describes how to tell Neovim how Pyrefly can be run, as well as how to override those settings.

You have two options on how to do this:

  1. (recommended) Install or update the neovim/nvim-lspconfig plugin to get Pyrefly's (and other language servers') default configs. You can override specific settings if you'd like.
  2. Setup your language server manually without installing extra plugins.
Configs with neovim/nvim-lspconfig plugin

neovim/nvim-lspconfig is a Neovim plugin acting as a repository of language server settings (a repository of language server settings) installed and updated to get Pyrefly's default configuration.

We also recommend installing or updating the mason-org/mason-lspconfig.nvim plugin if you're using Mason, which provides other nice functionality when using Mason with lspconfig. If you install mason-org/mason-lspconfig.nvim, be sure to source it in your Neovim config.

To override specific settings, see :h vim.lsp.config. See :h vim.lsp.Config and :h vim.lsp.ClientConfig for values you can override, and the nvim-lspconfig Pyrefly config for default values.

Example overriding cmd and filetypes

vim.lsp.config('pyrefly', {
-- example of how to run `uv` installed Pyrefly without adding to your path
cmd = { 'uvx', 'pyrefly', 'lsp' }
})
No-plugin Configs

You have the option to setup your language server without neovim/nvim-lspconfig. Simply copy/modify the Pyrefly defaults from nvim-lspconfig in a block like below.

**NOTE: This should be in a file under nvim/lsp/pyrefly.lua

---@type vim.lsp.Config
return {
cmd = { "pyrefly", "lsp" },
}
tip

This Youtube tutorial explains setting up a language server in more depth and with a more organized setup, so check it out if you want to learn more.

info

Want full type-check squiggles in your editor by default? Run pyrefly init to create a pyrefly.toml (or update pyproject.toml), or add the following to the config object passed into vim.lsp.config to override the default auto-detect behavior:

{
settings = {
python = {
pyrefly = {
typeCheckingMode = 'default'
}
}
}
}
Enable Pyrefly for Neovim

If you've installed Pyrefly with Mason and have mason-org/mason-lspconfig.nvim installed, then your language server should just work! You can check by opening a file your language server should cover and running :checkhealth lsp to see if it's started. You may need to restart Neovim for any changes made above to take effect.

Otherwise, to make sure your language servers are activated, be sure to enable them with the syntax below.

vim.lsp.enable({"pyrefly"})
tip

If you're using init.vim, you can use a lua heredoc to execute lua and enable your config.

Vim/Neovim + coc.nvim

Ensure the pyrefly is on $PATH, add following snippet to your coc-settings.json:

"languageserver": {
"pyrefly": {
"command": "pyrefly",
"args": ["lsp"],
"filetypes": ["python"],
"rootPatterns": ["pyrefly.toml", "pyproject.toml", ".git"],
}
},
tip

For projects without a Pyrefly configuration, Pyrefly defaults to the basic preset (a small set of high-confidence diagnostics). To switch to a stricter preset for files not covered by a pyrefly.toml, add the following initializationOptions:

"languageserver": {
"pyrefly": {
"command": "pyrefly",
"args": ["lsp"],
"filetypes": ["python"],
"rootPatterns": ["pyrefly.toml", "pyproject.toml", ".git"],
"initializationOptions": {
"pyrefly": {
"typeCheckingMode": "default"
}
}
}
}

Available values: "auto" (the default; auto-detects a nearby mypy/pyright config or falls back to basic), "off", "basic", "legacy", "default", "strict". To suppress all diagnostics in this workspace regardless of preset, use "disableTypeErrors": true instead.

Vim + ALE

Pull the latest version of ALE and add the following lines to your configuration to enable Pyrefly in Vim with ALE:

let g:ale_linters = {
...
\ 'python': ['pyrefly'],
...
\ }

Emacs

There are several emacs packages that implement the language server protocol; the eglot package is built into recent versions of emacs. You can tell eglot to use pyrefly (which we assume is on your $PATH) with the following configuration:

(add-to-list 'eglot-server-programs
`((python-ts-mode python-mode) . ("pyrefly" "lsp")))

If you are using use-package, this command would run inside of the :config block; a minimal example would look like this:

(use-package eglot
:ensure t
:hook ((python-mode python-ts-mode) . eglot-ensure)
:config
(add-to-list 'eglot-server-programs
`((python-ts-mode python-mode) . ("pyrefly" "lsp"))))

Helix

Ensure that pyrefly is on $PATH (If you got Pyrefly using pip install pyrefly, it should already be on your path). Add this snippet to your languages.toml file

[language-server.pyrefly]
command = "pyrefly"
args = ["lsp"]

[[language]]
name = "python"
language-servers = ["pyrefly"]

Sublime

See the documentation here.

Positron

Positron comes with Pyrefly out of the box. See the documentation here.

Marimo

Pyrefly provides language services to Marimo notebooks. See Language Server Protocol for how to enable it.

Jupyter Lab

Pyrefly may be used in Jupyter Lab through the jupyterlab-lsp extension. Once the extension is installed, Pyrefly will appear on the list of automatically-detected language servers.

tip

Unlike in VS Code, autocomplete in Jupyter Lab is not automatically-triggered as you type. To enable this, enable Code Completion & Continuous Completions in the Jupyter Lab Settings.

Out of the box, Jupyter Lab's go-to-definition will not navigate to dependencies outside of your project. To enable this behavior:

  1. Go to your project directory and run ln -s / .lsp_symlink
  2. When launching Jupyter Lab, use jupyter lab --ContentsManager.allow_hidden=True

Zed

Zed users can install the Pyrefly extension from here or by visiting the extensions marketplace:

Here's an example of a Zed config with Pyrefly integration:

{
"lsp": {
"pyrefly": {
"binary": {
"path": ".venv/bin/pyrefly",
"arguments": ["lsp"]
}
}
},
"languages": {
"Python": {
"language_servers": ["pyrefly"],
}
}
}