Lessons from Pyre that Shaped Pyrefly

Source: pyrefly.orgDate: 2026-03-24Rating: ⭐⭐⭐⭐⭐
Python Type Checking Rust OCaml Language Server

Overview

Pyrefly is Facebook's next-generation Python type checker and language server, successor to Pyre. This article shares key lessons from Pyre's development that influenced Pyrefly's design.

Key Insight: Pyrefly addresses Pyre's fundamental architectural limitations by building a system flexible enough to handle both throughput-oriented workloads (CLI type checking) and latency-sensitive workloads (IDE/language server).

Key Lessons

1. Language-Server-First Architecture

Pyre was originally designed as a CLI tool prioritizing throughput (parallel CPU usage). Adapting it for IDE use caused problems:

Solution: Pyrefly built for flexibility from the start, plus uses Ruff parser for better error recovery during parsing.

2. OCaml vs Rust: Ecosystem as a Ceiling

Pyre was implemented in OCaml. While it bootstrapped quickly, limitations emerged:

Solution: Rust treats Windows, macOS, and Linux as true equals. Cross-platform reliability is foundational. Also enabled faster community growth.

3. Irreversible AST Lowering

Pyre used AST transformation passes to accelerate development (e.g., lowering Union[X,Y] to X | Y). However, this caused problems:

# Original code
from foo import x
def test():
    y = x
    x = "bar"
    z = x

# Transformed (lost critical info)
from foo import x
def test():
    y = foo.x  # lost: test() never references module foo!
    _local_test_x = "bar"
    z = _local_test_x

Solution: Pyrefly minimizes AST fabrication/transformation to preserve source location info for language server features.

4. Attribute Narrowing: Soundness vs Usability

Pyre's strict security focus led to strict type narrowing rules:

# Pyre complained even after isinstance check
class C:
    x: int | str = ...

def narrowing_test(c: C) -> int:
    if isinstance(c.x, int):
        some_other_function(c)
        return c.x  # Pyre: might still be str!

Users had to manually assign to local variables. Solution: Pyrefly allows this narrowing, prioritizing usability over strict soundness.

Significance

This article provides rare insight into how major tech companies evolve their developer tools. The lessons about language server architecture, ecosystem limitations, and usability tradeoffs are applicable beyond Python type checking.


Original Article