Pyrefly: Python type checker and language server in Rust
47 comments
·October 14, 2025sirfz
jswny
At least for Ty, not sure about the others, it is explicitly for type checking, exposed as an LSP. It’s not trying to compete with full LSP implementations. Most modern editors let you combine multiple LSPs, you shouldn’t think of them as using only one at a time
null
sheepscreek
I much prefer the rigidity of pyrefly. It enforces a standard expectation across the code base, which will lead to less surprises IMO.
scosman
Anyone know how this compares to 'ty': a new typechecker from Astral (uv/ruff team), also written in Rust and super fast. I had been waiting on it to reach beta, but would love to move to something faster than pyright sooner if possible.
emddudley
Pyrefly vs. ty: Comparing Python’s Two New Rust-Based Type Checkers (2025-05-27) https://blog.edward-li.com/tech/comparing-pyrefly-vs-ty/
HN discussion of above: https://news.ycombinator.com/item?id=44107655
How Well Do New Python Type Checkers Conform? A Deep Dive into Ty, Pyrefly, and Zuban (2025-08-29) https://sinon.github.io/future-python-type-checkers/
pawelkobojek
I love the speed advantage of pyrefly over (based)pyright but so far it doesn't seem to highlight as much as pyright does, for example it doesn't catch unreachable code like this:
def fn(x: str):
if x is None:
x = "123" # pyright flags that as unreachable code, pyrefly does not
Autocomplete for modules also doesn't work for me yet: import os
os. # I'll get `ABC, `Any`, `AnyStr`, `AnyStr_co`, `BinaryIO`, ...
Looking forward to have a fast language server for python though, pyright is way too slow for large projects.giancarlostoro
It's funny because in other typed languages a string can be null because of string being a reference type as opposed to a value type. I think Python type hints make more sense than C# does in this respect, which gives me a chuckle (two of my favorite languages and the untyped one makes more sense with types). That said, not sure if you already have but I would add a github issue / ticket reporting your issue to raise awareness to the devs.
Scarblac
All Python types are reference types. The reference to None isn't included in the str type.
There's no way to get an actual null reference, afaik. Variables always have some value, possibly None.
(not sure what happens if you set a reference to null from C - a crash, probably?)
_flux
In some other typed languages, that is. E.g. in C++, OCaml, Haskell, F#, Kotlin, and Rust (a non-exhaustive list) you can have non-nullable strings, and other objects.
asplake
It’s worth noting that even though the runtime allows nulls (i.e. None) anywhere, Python type checkers do distinguish between optional and mandatory types.
parhamn
Whats the expected error in the example you gave? That x can't be none because it was received as a str?
wiz21c
isn't it perfectly valid to pass None to that function ? It's not like python enforces types at runtime nor at compile time. Right ?
pawelkobojek
Exactly - something along the lines of "Statement is unreachable".
robertlagrant
Yes, exactly. x would have to be str | None to be reachable.
boxed
Or that x is unused?
veber-alex
Yeah I have a similar experience with ty.
Looks like none of these new type checkers are ready yet.
f311a
Ty has autocomplete for imports, but it's hidden behind a toggle right now. They are still working on it. They index all the modules and functions, so you can just type the function name and it will suggest the correct import and insert it.
bobajeff
Though, I'm happy with basedpyright and usually disable type checking. It's great to have so many options in language servers for Python now that pylance is locked to vscode.
brianzelip
See the recent Talk Python podcast featuring some Pyrefly team members, https://talkpython.fm/episodes/show/523/pyrefly-fast-ide-fri...
rasulkireev
This looks interesting. But I decided to go with ty in my projects, for the incremental approach.
codethief
How well does ty work these days? Last time I checked it still produced a lot of false positives and false negatives. (Which was very much expected, given its alpha/WIP status.)
flanked-evergl
Sadly, the question with both this and ty is: Does it support pydantic? If not, then it's not really helpful for many people, and right now AFAIK neither supports pydantic.
Pydantic is probably the problem here, but it is what it is.
phailhaus
Python's type system is the problem here, which cannot support even the native dataclass pattern and needs custom plugins written for each type checker.
whalesalad
Python is starting to feel a bit like JavaScript circa 2014. Remember grunt, gulp, webpack, coffeescript, babel? Now we've got pyright, mypy, pyrefly, black, ruff, ty, flake8, poetry, uv...
I used to find this kind of tooling explosion exhausting (and back then with JS it truly was), but generally speaking it's a good sign that the community is hungry to push things forward. Choice is good, as long as we keep the Unix spirit alive: small, composable tools that play nicely together and can be interchanged.
pjmlp
Pity that is all looking like Rewrite in Rust looking for solution, instead of actually improving JIT tooling capabilities.
There is a reason us old timers mostly wait on the sidelines until the dust settles.
We have seen this movie already too many times.
parhamn
Interestingly besides typescript, javascript in 2025 is still super fragmeneted but by a bunch of well-polished tools that all do approximately the same thing. esbuild/vite(rollup)/trubopack(swc), prettier/biome/oxc, npm/bun/pnpm/yarn, bun/node/deno/worker-runtimes
strangescript
"grunt, gulp, webpack, coffeescript, babel" --- except no one uses these anymore and they are dead outside of legacy software.
The problem with the python tooling is no one can get it right. There aren't clear winners for a lot of the tooling.
jon-wood
I think that's the point. Every now and then a language will have a small explosion of new tooling, and all you can really do is wait for it to blow over and see what tools people adopted afterwards, it feels like Python is going through a period like that at the moment.
insane_dreamer
I've tried pyrefly, ty, pyright, and basedpyright, with a large complex code base written using PyCharm, and _none_ of them do as good a job as PyCharm, particularly in discovering more complex type inheritances. It's a pity because in other respects Zed (which relies on these) is a worthy competitor to PyCharm (and much faster!) -- but the endless squiggly lines because pyrefly can't figure out the type, is annoying (and turning off the warnings is unhelpful). Hopefully one of these will get up to PyCharm's level (my money would be on ty as Astral is kicking a* these days).
f311a
PyCharm has very basic type checking, though. It's not strict.
> pyrefly, ty, pyright, and basedpyright
All of them will complain 2-4x more about your code than PyCharm. I had more than 300 typing errors when I first opened my 20k LOC project in pyright that I wrote in Pycharm.
PyCharm works great when your code is not annotated. It infers types very well. But it won't complain in a lot of cases when your code is annotated.
Related reddit post https://old.reddit.com/r/Python/comments/1ajnikt/to_pycharm_...
giancarlostoro
I think the 2nd best IDE for Python for me is Visual Studio proper, not Code. I know it sounds crazy, but Microsoft actually put some effort into their Python integration. Again, its a 2nd best, but that still says a lot about everyone else's editors.
Nowadays I'm finding myself using Zed a lot more, so maybe the story will be that all these nice Rust based tools become baked in giving it super powers for Python.
zelphirkalt
Another one I recently discovered and that has a very active maintainer is "zuban" or zuban-ls. It has replaced jedi-language-server for me, and aims to replace mypy as well.
f311a
Yeah, there are now 3 competitors and they all written in Rust:
- zuban
- ty (from ruff team)
- pyrefly
One year ago, we had none of them, only slow options.
tialaramex
Speed is one of those "Quantity has a quality all its own" things. We use very fast tools in a qualitatively different way, even though all that changed was how long it takes in seconds.
It is interesting that nobody was writing these tools in C or in C++. There are obvious ergonomic reasons, but perhaps also it matters that Rust cares a lot more about types than either of those languages.
f311a
It's just very hard to write such systems in C/C++. Even all these Rust versions are segfaulting and panicking quite a lot. So many corner and edge cases that can be found in Python code, and the memory handling is also hard.
The author of Zuban started writing it back in 2020 or 2021, so it took him more than 4 years to complete it. And he is the author of Jedi, so he had prior experience already.
jerrygenser
Basedpyright is not rust but it's a fork of pyright with added features that are otherwise locked in vscode
f311a
It's written in Typescript, which is a super weird choice.
jon-wood
I'm sorry, I can't take seriously any piece of software which decided to prefix the previous version's name with "based". I'm aware this is a me problem.
drcongo
It's also horrible for fasle positives unless your project happens to be the exact same setup as the maintainers' - I had to turn off the actual type checking on it. I've since moved wholesale to the Ty alpha and it feels a hell of a lot smarter.
rana762
[dead]
I've decided to to try out Pyrefly, Ty and Zuban for their language server features (type checking disabled where possible) last week and found that Zuban is the fastest (but unfortunately doesn't currently have the option to disable type checking). Ty comes next and Pyrefly was surprisingly slow to load (have to wait a few seconds before I can goto definition for example).
They all lack certain features vs basedpyright (what I was using) such as auto imports (Ty has experimental support), showing signature/doc when selecting autocomplete options (I think Ty does have this one) and some other features that I can't remember.
One feature that always existed in Jedi (and now also Zuban) is "goto declaration" in Python. It allowed me to goto the "import" instead of the original definition of a function/class which I'm surprised either isn't supported at all (pyright?) or would just do the same thing as "goto definition" (Ty), seems like an obvious oversight imho.
Edit: Also, I wish all these new tools give more importance to such IDE features as much as they do for type checking.