Skip to main content

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

QuestionmypyPyrightPyrefly
What is it written in?PythonTypeScriptRust
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?NoYesYes
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 containersSome inference: return typesAdvanced inference: empty containers, parameters, and return types
Can it automatically add type annotations to my codebase?NoNoYes, with pyrefly infer
Pydantic supportPluginPartial support via dataclass_transformBuilt-in
Django supportPluginPartial support via stubsBuilt-in
attrs supportBuilt-inPartial support via dataclass_transformBuilt-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:

CheckerSettingWhat it enables
mypystrict = trueA bundle of optional checks. Which checks the bundle contains changes between releases.
PyrighttypeCheckingMode = "strict"Pyright's strict rule defaults, which can be overridden per rule.
Pyreflypreset = "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

References