A sandboxed Python subset with classes, async/await, structural pattern matching, and packages.json imports, compiled to bytecode and run on a stack VM with adaptive inline caching and pure-function memoisation. See Design for internals.
Reads like Python (parses Python syntax). Runs differently, what it executes is curated.
What it supports
- First-class functions: pass them, return them, store them in lists and dicts. Decorators apply to both
defandclass. - Lambdas with closures: full lexical capture by value-snapshot at
MakeFunction, currying, partial application. - Generators and coroutines:
yield,yield from,async def,await. Generator expressions are eagerly materialised to lists; use adefwithyieldfor true laziness. - Comprehensions: list, dict, and set, with multiple
forclauses andifguards. - Pattern matching:
match/casewith literals, captures, OR-patterns, guards, and sequence patterns (one star permitted). - Exceptions:
try/except/else/finally, named handlers,raise X from Y(chain info discarded butXis what propagates), and subclass-aware matching (except ExceptioncatchesRuntimeError). - Context managers:
withandasync withinvoke__enter__/__exit__on the context-manager value; a truthy return from__exit__suppresses the raised exception. - Protocol dunders: operator overloading, indexing, iteration, hashing, and
repr/str/formatdispatch through user-defined dunders, see Dunders for the full matrix. - Numbers: integers up to
±2^127(auto-promoted past 47 bits; beyond the cap raisesOverflowError) and full IEEE-754 floats. Nocomplex,Decimal,Fraction, or arbitrary precision beyond 128 bits. - Sequences: lists, tuples, dicts (insertion-ordered), sets, frozensets, ranges, strings (UTF-8, codepoint-indexed), and bytes.
- f-strings: full grammar, embedded expressions,
{expr=}self-doc,!r/!s/!aconversions, and format specs coverings d b o x X f F e E g G n % cplus fill / align / sign /#/0/ width /,/ precision. - Walrus operator:
:=in expressions (Name target only). - Type annotations: parsed and discarded, no runtime
__annotations__, no enforcement. - Module identity:
__name__is bound to"__main__"in the entry chunk and to the module’s spec inside imported modules, so the canonicalif __name__ == "__main__":guard works as expected. - Modules:
import,from <spec> import names, andfrom <spec> import *resolve at parse time through a host-injected resolver, with optional#sha256-<hex>integrity on URL specs. Two flavors:.pysource modules and native modules, see Imports for resolution semantics, Writing modules for the three delivery paths, and Official packages for the ready-made modules (json,dom,network,storageand more).
What it doesn’t support
These parse for syntactic compatibility but raise at runtime, or simply don’t exist:
- Standard library: no bundled stdlib; every module is external (see Modules above).
- I/O:
input()reads from a host-provided buffer. There is no file system, no network, noos, nosys, those surface only when the host runtime registers them as host packages (the same mechanism behindprintandinputthemselves). - Async surface:
async defcreates real coroutines and the VM runs a cooperative scheduler, but there is noasynciomodule; primitives are top-level builtins (run,sleep,gather,with_timeout,cancel,receive). Coroutines do not expose.send()/.throw()/.close(). - Metaclasses, descriptor protocol,
__slots__: not modeled. - Dynamic code: no
exec, noeval, nocompile, no__import__(use theimport_module(name)builtin to look up an already-imported module by alias). - Reflection beyond
type,id,hash,repr,callable,getattr,hasattr,vars,globals,locals,isinstance,issubclass.diris absent. - Relative imports:
from . import xis not supported; use the resolver-awareimport/from <spec> importforms.
Design philosophy
Multi-paradigm sandboxed compiler:
- Smaller binary, compiler + VM in 170 KB WebAssembly release.
- Faster interpreter, no method-resolution overhead; hot opcodes promote to type-specialised fast paths via IC.
- Aggressive memoisation, pure functions auto-cached; most functional code is pure by construction.
- Easier sandboxing, no protocol dispatch, no stdlib; attack surface is the fixed built-in set.
Sandbox guarantees
Inherits WASM-host guarantees (no syscalls, no FS, no network, isolated linear memory). On top, embedders enforce per-VM caps via Limits::sandbox(), hits raise recoverable RuntimeError / MemoryError / RecursionError rather than crashing the host. See Limits and errors.
Where it runs
Single .wasm artifact (compiler_lib.wasm, 170 KB), runs anywhere WebAssembly does:
- Browser: served alongside the
runtime/JS package, which bridgesprint()and module imports across theWASM <-> JSboundary. - Server / edge runtimes: Wasmtime, Wasmer, Cloudflare Workers, Fastly Compute, Spin. The host runtime owns I/O, fetching, and module loading.
- Embedded Rust apps: load
compiler_lib.wasmvia your runtime of choice or use thecompiler_librlib when cargo-linked.
Two ABIs sit on top:
Compiler <-> hostimports, embedder-declared, covering output, module fetching, native dispatch, wall-clock time. Custom embedders that ship host packages declare additional imports (DOM, FS) without touching the plugin ABI.- Plugin ABI (sealed v1), contract for CDN-distributed
.wasmplugin modules. Exactly 6env.*imports, never extended. See the WASM module ABI.