website/docs/IDE.mdx
{/*
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.
:::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.
:::
By default, Pyrefly should work in the IDE with no configuration necessary. But to ensure your project is set up properly, see configurations.
The following configuration options are IDE-specific and exposed as VSCode settings:
python.pyrefly.typeCheckingModeType: 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.disableTypeErrorsType: 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.diagnosticModeType: 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.disableLanguageServicesType: 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.disabledLanguageServicesType: 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.configPathType: 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.streamDiagnosticsType: 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.syncNotebooksType: boolean Default: true
If true, Pyrefly will sync notebook documents with the language server. Set to false to disable notebook support.
python.pyrefly.runnableCodeLensType: boolean Default: false
Enable Pyrefly's Run/Test CodeLens actions for Python files.
python.analysis.showHoverGoToLinksType: 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.completeFunctionParensType: boolean Default: false
Automatically insert parentheses when completing a function or method.
pyrefly.lspPathType: string Default: ""
If your platform is not supported, you can build pyrefly from source and specify the binary path with this setting.
pyrefly.lspArgumentsType: array of strings Default: ["lsp"]
Additional arguments passed to the binary at pyrefly.lspPath.
pyrefly.trace.serverType: enum (off, verbose) Default: "off"
Set to 'verbose' to enable LSP trace output in the console. Useful for debugging LSP communication issues.
pyrefly.commentFoldingRangesType: 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.defaultInterpreterPathType: 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.
initializationOptionsWhen 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
}
}
}
pyrefly/textDocument/typeErrorDisplayStatusThird-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.
If you experience issues with the Pyrefly extension, please create an issue on github.
Support for other editors is community-driven. If you would like to set this up, please contribute.
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.
<video src="/videos/openvsx.mp4" width="720" muted loop autoPlay playsInline preload="metadata" />
PyCharm users can enable native Pyrefly support in the settings:
Go to Python | Tools | Pyrefly in the Settings dialog.
Select the Enable checkbox.
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.
Select which options should be enabled.
For more information, refer to PyCharm documentation.
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:
neovim/nvim-lspconfig, mason-org/mason.nvim, and mason-org/mason-lspconfig.nvim plugins with your plugin manager of choice.init.lua:require("mason").setup()
require("mason-lspconfig").setup()
:MasonInstall pyrefly or add pyrefly to your ensure_installed options:require("mason-lspconfig").setup {
ensure_installed = { "pyrefly" },
}
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`](https://github.com/neovim/nvim-lspconfig).
:::
<details>
<summary>Install Pyrefly for Neovim</summary>
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.
<details>
<summary>mason.nvim</summary>
[mason.nvim](https://github.com/mason-org/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`.
</details>
<details>
<summary>System Installations</summary>
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](#configure-pyrefly-for-neovim) 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](./installation.mdx) 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](#configure-pyrefly-for-neovim).
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.
</details>
</details>
<details>
<summary> Configure Pyrefly for Neovim</summary>
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`](https://github.com/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.
<details>
<summary>Configs with `neovim/nvim-lspconfig` plugin</summary>
[`neovim/nvim-lspconfig`](https://github.com/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](https://github.com/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](https://github.com/neovim/nvim-lspconfig/blob/master/lsp/pyrefly.lua) for default values.
Example overriding `cmd` and `filetypes`
```lua
vim.lsp.config('pyrefly', {
-- example of how to run `uv` installed Pyrefly without adding to your path
cmd = { 'uvx', 'pyrefly', 'lsp' }
})
```
</details>
<details>
<summary>No-plugin Configs</summary>
You have the option to setup your language server without
`neovim/nvim-lspconfig`. Simply copy/modify the Pyrefly defaults
from
[`nvim-lspconfig`](https://github.com/neovim/nvim-lspconfig/blob/master/lsp/pyrefly.lua)
in a block like below.
**NOTE: This should be in a file under `nvim/lsp/pyrefly.lua`
```lua
---@type vim.lsp.Config
return {
cmd = { "pyrefly", "lsp" },
}
```
</details>
:::tip
[This Youtube tutorial](https://youtu.be/IZnhl121yo0?si=VINhYDEySX48_8GY) 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'
}
}
}
}
```
:::
</details>
<details>
<summary>Enable Pyrefly for Neovim</summary>
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.
```lua
vim.lsp.enable({"pyrefly"})
```
:::tip
If you're using `init.vim`, you can use a [lua heredoc](https://neovim.io/doc/user/lua.html#%3Alua-heredoc) to execute lua and enable your config.
:::
</details>
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.
:::
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'],
...
\ }
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"))))
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"]
See the documentation here.
Positron comes with Pyrefly out of the box. See the documentation here.
Pyrefly provides language services to Marimo notebooks. See Language Server Protocol for how to enable it.
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:
ln -s / .lsp_symlinkjupyter lab --ContentsManager.allow_hidden=True
:::Zed users can install the Pyrefly extension from here or by visiting the extensions marketplace:
<video src="/videos/zed.mov" width="720" muted loop autoPlay playsInline preload="metadata" />
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"],
}
}
}