If you're on mypy in 2026, Pyrefly is the obvious upgrade
The case for staying on mypy has often been migration cost. Pyrefly 1.0, released May 12, 2026, makes the mechanical half close to free:
uv add --dev pyrefly
uv run pyrefly init
uv run pyrefly check --baseline=pyrefly-baseline.json --update-baseline
uv run pyrefly checkpyrefly init reads an existing mypy.ini or [tool.mypy] section, writes the equivalent Pyrefly configuration, and turns on a preset called legacy that disables the checks mypy does not have. Pyrefly’s inference is more aggressive than mypy’s on the checks both tools run, so a real codebase will surface new diagnostics on the first check pass. The count depends on the codebase and how much was typed before. The baseline-snapshot step writes those errors to JSON so the final check returns clean and CI stays green while the team triages on its own schedule.
That is the news. The rest of this post explains what each command is doing and what the new diagnostics actually look like.
The legacy preset plus a baseline file is the workflow
One common failure mode for mypy migrations is the wall-of-errors problem: a fresh checker surfaces every diagnostic mypy had silently ignored, and the resulting issue list is too big to triage without freezing the merge queue. Pyrefly 1.0 splits that problem in half.
When pyrefly init detects a mypy config, it writes preset = "legacy" into the generated file. That preset disables the checks mypy does not have at all, including bad-override-mutable-attribute and unbound-name. The preset is necessary but not sufficient. Pyrefly’s inference is more aggressive than mypy’s on the checks both tools run, so a real codebase will still see new diagnostics. Running pre-commit through the migration produced 47 missing-stub diagnostics (the same ones mypy reports) and 69 new ones from Pyrefly’s tighter inference. The 69 look like legitimate type bugs mypy missed: modules whose method signatures do not actually conform to a Protocol, and super().method() calls that reference methods the parent does not define.
Baseline files close the loop. pyrefly check --baseline=pyrefly-baseline.json --update-baseline snapshots the current set of errors to JSON. Subsequent checks pick up the baseline and report only diagnostics that are new since the snapshot, so CI stays green while the team works through the 69 on its own schedule. For a worked example on pre-commit and the setup.cfg gotcha that bites projects keeping mypy config in setup.cfg, see how to migrate from mypy to Pyrefly.
The other 1.0 change that matters here is quieter but just as load-bearing. Pyrefly now reads [tool.pyrefly] from pyproject.toml. Older articles, including earlier versions of the handbook’s comparison page, flagged the lack of pyproject.toml support as a coexistence problem. That friction is gone.
Track adoption with pyrefly report
Once the codebase passes, the next question is “what fraction of this is actually annotated?” pyrefly report answers it. The command emits JSON with annotation-completeness and type-completeness statistics at every level from function to module, plus an aggregate summary.
The output slots cleanly into CI: pin the current floor, fail the build if a PR regresses it. Combined with experimental baseline files (which snapshot the current set of errors and report only new ones on subsequent runs), the workflow described in how to gradually adopt type checking in an existing Python project is now a Pyrefly-native flow rather than a pattern teams have to assemble themselves.
What 1.0 means beyond the migration story
The migration tooling is the lead, but 1.0 also raised the floor on the metrics teams cite when they pick between checkers.
Conformance to the Python typing spec test suite climbed from 70% at beta to 92.2%. That puts Pyrefly ahead of mypy (59.6%) and ty (still in beta, at 67.4%), behind pyright (95.7%) and Zuban (99.3%). Conformance scores measure how closely each checker implements the typing spec, which is the contract library type stubs are written against. It is not a measure of bugs caught in application code, as Rob Hand’s analysis of the new type checkers argues at length.
Performance shipped against the February baseline: 2-125x faster diagnostics after save, 40-60% less memory, 20-36% faster full project checks on PyTorch and Pandas. The numbers come from open-source type_coverage_py and ty_benchmark suites. Meta also dropped the release cadence from weekly to monthly.
Meta announced Pylance compatibility through the Type Server Protocol (TSP) as upcoming work. If it lands, Pyrefly will run as Pylance’s analysis backend in any TSP-aware editor. That would mean Cursor, VSCodium, and Positron users could pair Pylance’s hover and rename refactoring with Pyrefly’s analysis, which would close the editor gap that’s been the standing argument for staying on Microsoft VS Code.
What about ty?
ty makes a different bet than Pyrefly. Its gradual guarantee promises that adding annotations to working code never introduces new errors. For a codebase not yet under any type checker, that promise is genuinely useful and Pyrefly’s aggressive inference will surface more diagnostics on first run. The FastAPI migration to ty is the most thorough write-up of how that plays out in practice.
For a codebase already on mypy in 2026, the legacy preset plus baseline files lets the migration be one command followed by incremental triage rather than a multi-quarter project. Astral’s acquisition by OpenAI earlier in 2026 is a separate variable to weigh: some teams will read it as a positive signal for ty’s resourcing, others as a strategic uncertainty.
mypy 2.0, released a week earlier, is the answer for teams that want speed without leaving the mypy ecosystem at all. Parallel checking via --num-workers closes part of the speed gap. The conformance gap stays open.