CLI tool
zubanls/zuban avatar
zubanls/zuban

Zuban: a Rust written Python type checker and language server

Python Type Checker / Language Server

1,226 stars44 forksRustNOASSERTION

At a glance

What is it?
Zuban is a Python type checker and language server written in Rust by the author of Jedi, offering a PyRight-like mode and a Mypy-compatible mode that reuses Mypy config files, flags and error messages, and it is published on PyPI.
Who is it for?
Zuban fits a team that already uses Mypy and wants the same checks and the same configuration without the wait, and the Mypy-compatible mode makes the switch a matter of changing the command in CI. It does not fit a team that needs a type checker nobody can complain about, since the project is AGPL and offers a separate commercial licence.
Can I use it commercially?
Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
Is it still maintained?
Yes. The repository received new commits within the last day.
What is it written in?
Mainly Rust, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

What Zuban is

Zuban is a Python language server and type checker implemented in Rust, by the author of Jedi. The homepage is zubanls.com, the documentation is at docs.zubanls.com, and the releases are published on PyPI as the zuban package.

The performance claim in the README is the headline: 20 to 200 times faster than Mypy, while using roughly half the memory and CPU compared to Ty and Pyrefly. The comparison is between named tools on the same kind of workload, and the numbers come from the project itself, so a reader should treat them as the author's measurements rather than an independent benchmark.

What the tool does is static analysis of Python. The README says it offers comprehensive support for Python's type system, linking to the typing conformance results, and it lists the language server features as diagnostics, completions, goto, references, rename, hover and document highlights. That list covers what an editor integration needs to be genuinely useful.

The project is young but moving. The recent releases are v0.9.3 on 2026-09-02, v0.10.0 on 2026-09-18 and v0.10.1 on 2026-10-11, and the last push to the repository was on 2026-10-15. The workspace version in Cargo.toml matches the latest tag, 0.10.1, and the Rust edition is 2024 with a minimum toolchain of 1.92.

Two modes, and why the second one matters

Zuban exposes two ways to use it, and the difference between them is the most important design decision in the project.

The first is a PyRight-like mode, exposed as zuban check. This is the mode for a project that wants Pyright style checking, with the editor features and a checker that reports errors the way Pyright reports them.

The second is a Mypy-compatible mode, exposed as zuban mypy, with the alias zmypy. The README is specific about what that means: it behaves just like Mypy, supporting the same config files, command-line flags and error messages. That is a much stronger promise than merely accepting a Mypy config file. The output is expected to be the output a team already parses in CI, and the flags are the flags a team already passes.

The reason this matters is the adoption path. Switching a large project to a new type checker usually means a new configuration, a new error format and a new set of suppressions, and the work is measured in weeks. A mode that accepts the existing configuration and produces the existing messages turns the switch into a command change, and the speed difference then shows up in the edit loop rather than in a nightly job.

The README also states that Zuban passes over 95 percent of Mypy's relevant test suite, which is the concrete measure of how close the compatibility mode is. That number is a project claim about a test suite Mypy itself defines, and the missing remainder is exactly the set of behaviours to check before trusting the mode on a codebase.

Installing Zuban and running it locally

The published package installs from PyPI with a single command:

bash
pip install zuban  # Installation

and the entry points follow a deliberate naming scheme:

bash
zuban check   # PyRight-like checking
zuban mypy    # Mypy compatibility mode
zmypy         # An alias for zuban mypy
zuban server  # An LSP server

The zmypy alias is a small thing with a large effect. A CI pipeline that calls mypy can be changed to call zmypy, and the alias exists so that a wrapper script, a pre-commit hook or a Makefile does not have to know which implementation is behind it.

The README also notes a dependency detail that trips people up: if you want Zuban to pick up your dependencies, the virtual environment has to be activated first, because the type checker resolves imports against the environment it is running in.

For development, the project is built with maturin and needs its submodules:

bash
pip install maturin
git clone --recursive https://github.com/zubanls/zuban
bash scripts/install-locally.sh

The README warns that the build will not work properly if the submodules are not cloned, which is why the clone command carries the --recursive flag. The repository has a .gitmodules file and a third_party/ directory, so the submodules are where the vendored parts of the type checking data live.

The crate layout and what it reveals

The workspace is a Cargo workspace with every crate under crates/, and the member list reads like a design document.

The parsing layer is parsa, with parsa_python for the Python grammar and parsa_python_cst for the concrete syntax tree. The virtual filesystem is a separate crate, vfs, which is what lets the type checker see a consistent view of the source and of the installed packages. typeshed_symbols holds the bundled type information. The two top level products are zmypy, the Mypy compatible front end, and zubanls, the language server. Around them sit the supporting crates: config for configuration, cli_args for the command line, logging_config, licensing, utils and test_utils.

The dependency list shows the engineering choices. Rayon provides the parallelism that a checker needs to use more than one core, crossbeam-channel and tracing handle the plumbing and the logs, lsp-server 0.7.9 provides the protocol server, and lsp-types is taken from a fork with the proposed features enabled, which is how a language server gets at the parts of the protocol that have not been finalised. The snapshot testing crate insta appears in the development dependencies, which fits a project whose claim is compatibility with an existing test suite.

The overall shape, a parser and a filesystem model feeding two front ends, is the shape you would expect from a type checker that wants to serve an editor and a command line from one analysis core, and that is why the two modes can agree with each other.

Dual licensing and the commercial option

Zuban is dual licensed, and the README states the two paths plainly.

The open source licence is the GNU Affero General Public License version 3. The terms are the standard ones: use, modify and distribute under the AGPL-3.0 terms, with the licence text in the LICENSE file at the repository root.

Alongside it, a commercial licence is available for organisations that would rather not comply with the AGPL, with the contact address given on the project's site. There is a licensing crate in the workspace, which is how a project ships both a free and a paid path from one codebase.

The AGPL is the part to think about carefully. It is the strongest of the common open source licences for a network service, because the copyleft reaches users who interact with the modified program over a network, not only people who receive the source. For a type checker used internally in a company, the usual reading is that internal use is fine. For a team that wants to build a hosted type checking service on Zuban, the AGPL obligation to offer the corresponding source to those users is a real constraint, and that is the situation the commercial licence addresses.

The repository metadata shows the licence as a custom one that GitHub cannot classify, which is consistent with a project that ships two licences under one repository, so the LICENSE file and the commercial terms are what a reviewer needs to read.

Where Zuban is the wrong tool

The first case is a project that needs the widest possible type system coverage right now. The README claims comprehensive support for Python's type system and a pass rate over 95 percent of Mypy's relevant test suite, but a type checker that is faster and slightly different will still report errors a project does not expect, and a project with a large suppression list will feel every one of them. The 95 percent figure describes the gap, and the gap has to be closed by fixing the checker or by adding suppressions.

The second case is a team that cannot accept the licence. A company with a policy against AGPL dependencies, or one that intends to run a hosted checker, has to buy the commercial licence, and the price of that conversation is part of the adoption cost.

The third case is a project that wants the very latest typing specification features. Zuban is a re-implementation that tracks the typing conformance results, so a brand new corner of the specification is likely to be supported later than in a checker written by the specification's own maintainers, and a project that lives at the edge of the specification will feel that.

Against the alternatives, the comparison is fairly direct. Mypy itself is slower but is the reference for the compatible mode, so a project that needs exact Mypy behaviour can keep Mypy. Pyright and Ty and Pyrefly are the direct competitors in the Pyright-like space, and Zuban argues it matches them on results while using less memory and CPU than two of them. For a team that has measured Mypy as the bottleneck and is willing to test a drop-in replacement, the case is straightforward; for a team that has not measured it, the speed claim alone is not a reason to switch.

Editorial conclusion

Zuban fits a team that already uses Mypy and wants the same checks and the same configuration without the wait, and the Mypy-compatible mode makes the switch a matter of changing the command in CI. It does not fit a team that needs a type checker nobody can complain about, since the project is AGPL and offers a separate commercial licence. Check first that your Mypy configuration is one the compatibility mode covers, because that mode is what makes the speed gain usable in an existing project.

Frequently asked questions

How do I install Zuban?

Run pip install zuban, which pulls the published wheel from PyPI. The commands are zuban check for the PyRight-like mode, zuban mypy and its alias zmypy for the Mypy-compatible mode, and zuban server for the language server.

What does Zuban's Mypy-compatible mode actually do?

The README states that zuban mypy behaves just like Mypy, supporting the same config files, command-line flags and error messages. Zuban passes over 95 percent of Mypy's relevant test suite, which is the stated measure of how close that mode is.

How fast is Zuban compared to other Python type checkers?

The README claims 20 to 200 times faster than Mypy, and roughly half the memory and CPU usage compared to Ty and Pyrefly. Those are the project's own measurements rather than an independent benchmark.

Can I build Zuban from source?

Yes. Install maturin, clone the repository with git clone --recursive so the submodules are included, and run bash scripts/install-locally.sh. The README warns that the build will not work properly if the submodules are not cloned.

Official sources

  1. Issues
  2. Project website
  3. README
  4. Releases
  5. zubanls/zuban on GitHub
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/zubanls-zuban.svg)](https://hysenlabs.com/projects/zubanls-zuban)

Was this useful?