Python 3.14 to Metal: Inside the No-Interpreter Runtime Experiment
A new Rust-based compiler bypasses bytecode entirely, compiling Python 3.14 directly to native machine code via Cranelift.
CPython 3.14 arrived with incremental runtime improvements, including standard library support for isolated subinterpreters and an experimental, opt-in copy-and-patch JIT compiler. While these updates make the default interpreter faster and more parallel, they are still evolutionary steps built on top of a thirty-year-old virtual machine.
A new project called pon is taking a far more radical approach. Written in Rust, pon is a JIT and ahead-of-time (AoT) compiler and runtime designed specifically for Python 3.14. It completely eliminates the interpreter, bytecode, and reference counting. Instead, it parses Python source code, lowers it to a custom intermediate representation, and compiles it directly to native machine code using the Cranelift generator backend.
This is not another wrapper or a restricted subset of the language. The project aims to be the Bun or V8 of the Python ecosystem, delivering single-binary executables and a multi-tier JIT while maintaining strict compatibility with CPython.
The Architecture: No Bytecode, No Interpreter
Traditional Python execution relies on compiling source code into bytecode, which is then executed by the CPython virtual machine. Even CPython's new copy-and-patch JIT operates by translating these bytecode instructions into machine code templates at runtime.
pon bypasses this entire abstraction layer. Its compilation pipeline is unified across both JIT and AoT execution paths:
- Parsing: The compiler uses the Ruff parser (pinned to version 0.14.0 with Python 3.14 syntax support) to generate an Abstract Syntax Tree (AST).
- Lowering: The AST is lowered into a single, shared intermediate representation called
pon-ir. - Codegen: The
pon-codegencrate translatespon-irinto Cranelift CLIF (Cranelift Intermediate Format). - Execution: Depending on the execution mode, Cranelift compiles this representation into machine code.
In JIT mode (pon run), the code is compiled in-process using cranelift-jit. In AoT mode (pon build), the compiler uses cranelift-object to emit native object files, which are then linked into a standalone, self-contained executable.
To manage performance, the JIT path uses a two-tier execution model. Tier-0 is a baseline compiler where all variables are boxed. This tier acts as the correctness baseline and collects type profiles via runtime helper functions. When a function becomes hot, a background thread recompiles it into Tier-1 (the typed tier), which uses inline caches and on-stack replacement to swap the running loop with optimized, type-specialized machine code.
Ditching Refcounts for "Green Tea" GC
One of the most significant architectural departures in pon is how it handles memory. CPython relies heavily on immediate reference counting, supplemented by a cycle detector to clean up reference loops. While reference counting provides predictable destruction, it introduces significant overhead. Every variable assignment, function call, and scope exit requires incrementing or decrementing reference counters, which causes frequent cache line invalidations in multi-threaded environments.
pon strips the reference count header entirely from its heap object layout. Instead, memory is managed by a custom garbage collector named Green Tea (pon-gc).
This change fundamentally alters how the runtime executes. In the baseline Tier-0 JIT, the collector performs conservative stack scanning, using a register-flush trampoline at designated safepoints to find object references. As the runtime transitions to the optimized Tier-1 JIT, it upgrades to precise stack scanning, utilizing Cranelift's native user stack maps to track references exactly.
By removing the reference counting overhead, the runtime can execute tight loops with significantly fewer memory writes, opening up a path to true multi-core parallelism without the historical bottlenecks of the Global Interpreter Lock (GIL).
The Developer Angle: Compilation and the Compatibility Catch
For developers, the workflow of pon looks closer to Go or Rust than traditional Python. You can run a script directly using the JIT compiler:
cargo run -p pon -- run script.py
Alternatively, you can compile the script into a standalone native binary that runs without any external Python dependency:
cargo run -p pon -- build script.py -o native_app
./native_app
To prove correctness, the project uses a byte-exact differential testing harness. A test case only passes if pon produces the exact same stdout and stderr bytes as CPython 3.14.0 under identical environment conditions. Currently, the JIT compiler passes this strict conformance test for 244 CPython corpus modules, while the AoT compiler passes for 206 modules.
However, this architectural elegance comes with a massive trade-off: ecosystem fragmentation.
Because pon eliminates the reference count header and changes the physical layout of Python objects in memory, it is fundamentally incompatible with CPython's C-API. Traditional C extensions like NumPy, PyTorch, or cryptography cannot run on this runtime out of the box. Instead, the runtime exposes a custom pon_* helper ABI where errors cross the boundary as NULL sentinels rather than C++ style unwinding.
If you want to run heavy scientific or machine learning stacks, pon is not a drop-in replacement today. It requires rewriting or specifically porting native extensions to its custom ABI.
The Verdict
pon is a highly ambitious engineering project that demonstrates what Python could look like if it were designed today with modern compiler toolchains. By leveraging Rust, Ruff, and Cranelift, it proves that compiling Python to native, dependency-free binaries with a modern garbage collector is entirely viable.
For CLI tools, web services with minimal native dependencies, and deployments on constrained environments like AWS Lambda, the promise of sub-millisecond startup times and single-file deployments is incredibly compelling.
But for the broader Python community, C-API compatibility is the gravity that keeps developers bound to CPython. Until pon or a similar native runtime solves the extension compatibility problem, this remains an incredibly impressive technical showcase rather than a production-ready alternative. It is worth keeping a close eye on, but do not delete your virtual environments just yet.
Sources & further reading
- Python 3.14 compiled to metal – no interpreter — github.com
- What's new in Python 3.14 — Python 3.14.6 documentation — docs.python.org
- windows - PyCharm keeps using a non-existent Python 3.14 interpreter even after removing it from the system - Stack Overflow — stackoverflow.com
- Issue with the interpreter in Visual Studio Code - Microsoft Q&A — learn.microsoft.com
Lenn writes about cloud platforms, Kubernetes internals, and the infrastructure decisions that quietly make or break engineering organizations. Based in Berlin's vibrant tech scene, they have a talent for turning dense platform-engineering topics into prose that people actually finish reading.
Discussion 3
interesting, but what's the attack surface look like?
@securepaws that's a great point, eliminating the interpreter does reduce the attack surface, but i'm curious to see how pon's custom intermediate representation holds up to scrutiny - and how it affects overall dx, hopefully it's not a tradeoff between security and polish
@frontend_fae yeah, security is great but if it's a pain to debug...