Before, when developing Django-based projects, I often use VS Code. Because VS Code is getting heavier and heavier (the installation is 1 GiB now), I need to move away from it. But the first thing is to find an independent LSP server that works well enough with Django. VS Code comes with Pylance, its LSP server for Python. But Pylance is proprietary, so for another code editor, I need a different solution.
When we do programming, LSP servers are great tools. They help improve productivity by enabling accurate autocomplete in code editors, allowing us to code faster and make less mistakes. They work best with languages having a strong type system (Rust and functional programming languages, like Gleam), because the type system lets us know, at any point, which type a variable has and what members it contains. For dynamic type languages, LSP servers are often based on static type checkers (because both need to draw type information from the source code). For Python, the situation is a bit hard, because Python is so dynamic and flexible that, its type annotations cannot cover all the cases to help type checkers and LSP servers infer the type of variables. It is especially true for Django. At the time of writing, Mypy is the type checker that supports Django the best. It means that, on the LSP server side, we need one that can take advantage of Mypy. Currently, there are many type checkers + LSP servers for Python, most of which are not written in Python:
-
Pyright: Written in TypeScript.
-
Zuban, Pyrefly, ty: Written in Rust.
Because of that, they cannot run the Mypy plugins that django-stubs provides to help resolve Django's dynamic types. Fortunately, I found python-lsp-server, which can talk with Mypy via its pylsp-mypy plugin. The installation is a bit tricky if we choose to install them outside the OS package managers (APT, dnf).
The simplest way to install is via OS package managers. For example, on Ubuntu, we just need to do:
sudo apt install python3-pylsp-mypy
That single command will install both python-lsp-server and pylsp-mypy.
If you don't want to install via OS package manager, because, for example, the OS repositories provide an outdated version of the software, then the only tool to use is pipx.
pipx is the tool to install Python applications from PyPI in an isolated virtual environment each. There are several tools in this category (you can also use uv tool). But only pipx supports installing extra packages to an existing isolated virtual environment, and python-lsp-server needs that.
To install python-lsp-server:
❯ pipx install python-lsp-server
installed package python-lsp-server 1.15.0, installed using Python 3.14.4
These apps are now available
- pylsp
done! ✨ 🌟 ✨
then, install the plugin:
❯ pipx inject python-lsp-server pylsp-mypy
injected package pylsp-mypy into venv python-lsp-server
done! ✨ 🌟 ✨
Check again:
❯ pipx list
venvs are in /home/quan/.local/share/pipx/venvs
apps are exposed on your $PATH at /home/quan/.local/bin
manual pages are exposed at /home/quan/.local/share/man
package python-lsp-server 1.15.0, installed using Python 3.14.4
- pylsp
Now we configure the code editor to let it use pylsp.
Helix
Helix can automatically detect pylsp. If it does not, add this to the ~/.config/helix/languages.toml file:
[language-server.pylsp]
command = "pylsp"
Then add this block to the same file:
[[language]]
name = "python"
language-servers = ["ruff", "pylsp"]
Or if you only want to use pylsp for a specific project, add that [[language]] block to the .helix/languages.toml file of the project.
Zed
Install the pylsp extension.
Then in ~/.config/zed/settings.json:
{
"languages": {
"Python": {
"language_servers": ["ruff", "pylsp"]
}
}
}
Now see pylsp in action:

With the help of Mypy, pylsp can suggest the extra attributes we define on a QuerySet, rather than on the model. This magic is what Pyright cannot do.
But... other than that, pylsp is not as complete in terms of pure LSP features—for example, hover doesn't work. So in non-Django projects, my choice of LSP + type checker is Zuban.
I got some feedback that, why do we have to install an LSP server independently, whereas in NeoVim people can just install a plugin. Yeah, the thing is, with this independent installation, you can share the LSP across many code editors and AI agents. For example, after installing python-lsp-server globally (not inside a plugin of some software), Crush, an AI agent, can automatically detect:

That's it. Let's enjoy coding and build great software together.
Updates
16 September 2026:
I realized that I was wrong. pylsp only uses mypy for type checking, producing diagnostics. It does not draw the extra attributes that mypy inferred (WithAnnotation). The autocomplete shown in the screenshot are actually from Helix's word autocomplete.