Mypy vs Pyright vs Pyrefly
This page sets out how mypy, Pyright, and Pyrefly differ, so you can judge whether moving to Pyrefly is worth it for your project. Every codebase has its own constraints, and which tool you should choose depends on what you find works best for your specific needs.
Where the sections below cite numbers, they come from the benchmarks and dashboards linked under References. All three tools make changes over time, so treat any figure as a snapshot and rerun it if the decision hinges on it.
At a glance
| Question | mypy | Pyright | Pyrefly |
|---|---|---|---|
| What is it written in? | Python | TypeScript | Rust |
| How fast is it? (benchmarks) | Slow (18.3s for pandas, 36.3s for pytorch) | Faster (8.8s for pandas, 16.7s for pytorch) | Fastest (1.5s for pandas, 2.1s for pytorch) |
| Can it be used as a language server? | No | Yes | Yes |
| How closely does it follow the typing spec? (dashboard) | 108.5/145 conformance tests (74.8%) | 135.5/145 (93.4%) | 140.5/145 (96.9%) |
| How is it configured? | mypy.ini, setup.cfg, or [tool.mypy] | pyrightconfig.json or [tool.pyright] | pyrefly.toml or [tool.pyrefly] |
| Can it infer types for code that has no annotations? (details) | Some inference: empty containers | Some inference: return types | Advanced inference: empty containers, parameters, and return types |
| Can it automatically add type annotations to my codebase? | No | No | Yes, with pyrefly infer |
| Pydantic support | Plugin | Partial support via dataclass_transform | Built-in |
| Django support | Plugin | Partial support via stubs | Built-in |
| attrs support | Built-in | Partial support via dataclass_transform | Built-in |
Choose Pyrefly when
- You need a faster language server or type checker, particularly if your large codebase currently struggles with Mypy/Pyright
- You want one project to power CLI checking and language-server features, so the two cannot drift apart;
- Your codebase uses Pydantic, Django, or attrs and you don't want the overhead of plugins
- You work on AI/ML workflows and are interested in new features like tensor shape checking (read the docs)
Pyrefly is not a reimplementation of either mypy nor Pyright and will not produce identical diagnostics. A successful migration ends in understood and accepted differences rather than in matching output.
Strict modes
Different type checkers have a different interpretation of what "strictness" means, and what the default strictness should be. How different checkers handle empty containers is a clear example of this, given x = [] followed by x.append(1), mypy and
Pyrefly infer the element type from that first use and flag a later
x.append("two"), while Pyright infers list[Any] and reports nothing.
Pyrefly's behavior here can be adjusted using the
infer-with-first-use config.
All three tools also have a setting called strict, and the three are not equivalent.
Each enables a different set of checks:
| Checker | Setting | What it enables |
|---|---|---|
| mypy | strict = true | A bundle of optional checks. Which checks the bundle contains changes between releases. |
| Pyright | typeCheckingMode = "strict" | Pyright's strict rule defaults, which can be overridden per rule. |
| Pyrefly | preset = "strict" | Pyrefly's strict error kinds and behavior settings. Any setting you specify overrides the preset. |
Because the bundles differ, code that passes one tool's strict mode will not
necessarily pass another's. When comparing configurations, it is more reliable
to look at the specific policies you care about, such as implicit Any, missing
annotations, override decorators, and unused ignores, than to match the strict
settings to each other. mypy strict mode and
Pyright strict mode cover what each one turns
on and their closest Pyrefly equivalents.
Try it alongside your current checker
# uv
uv add --dev pyrefly
# pip
python -m pip install pyrefly
To see what Pyrefly reports on your code without changing anything in the project:
pyrefly check
That works with no Pyrefly config. If Pyrefly finds an existing mypy or Pyright configuration and no Pyrefly config governs the files, it reads that configuration for the run without writing anything to disk.
Once you decide to go ahead, run pyrefly init to convert that configuration
into a native one you can commit. Check out
Migrate from mypy and
Migrate from Pyright for a more detailed
walkthrough.
Blocked by something?
If a specific feature, diagnostic, plugin, or configuration option is what stops you from adopting Pyrefly, please open an issue on GitHub. Gaps that block real migrations are the ones we prioritize.
Next steps
- Migrating from mypy: Migrate from mypy.
- Migrating from Pyright or Pylance: Migrate from Pyright.
- Starting from scratch: Installation and Configuration.
References
- Typing conformance results
from the
python/typingrepository. - Type checker performance dashboard, which reruns the benchmark daily.
- The Python typing specification.
- Speed and memory usage benchmarks a full check across 53 popular open-source packages, and explains what drives the spread between them.
- Typing spec conformance covers what the conformance suite measures, the current standings, and the limits of the score.
- Empty container inference
works through the three strategies checkers use for
x = []and the trade-offs of each. - Are you really expected to run five type checkers now? argues for running many checkers over your test suite and one over your source, which is useful if you maintain a library.