Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Overview

Perry-WIT compiles a static subset of TypeScript ahead of time into WASI 0.3 WebAssembly components. It lowers TypeScript through typed SSA directly to WebAssembly instructions and links only referenced functions from its precompiled runtime and standard libraries, so a component exporting a string function is about 3 KB. These #![no_std] modules ship inside the compiler, so compiling needs no Rust or LLVM toolchain, whether you use the CLI, the Rust API or the compiler as a sandboxed WASI 0.2 component (see Embedding and Architecture).

Programs are ordinary TypeScript that tsc checks against types generated from the WIT world, and modules without WIT imports also run under Node.js. A module can be a CLI command with top-level await, export functions or an HTTP handler, or do both, in which case its top-level code initializes state once before the first export runs (see Authoring). WIT integer types refine number: a u8 parameter is an integer in 0..=255. Forward range and backward bitwidth analysis turn in-range arithmetic into i32 and i64 instructions and drop proven bounds checks, while other numbers keep IEEE 754 f64 semantics (see Semantics and Standard Library).

Memory stays flat across calls: the test suite runs 1,000 calls with a nested record argument within two 64 KiB pages. When no export can suspend, keep state, hold host resources or allocate without bound, each call allocates from a region freed in bulk when it returns. Otherwise the runtime uses precise mark-and-sweep collection at compiled safe points. async functions compile to stackless state machines without a guest microtask queue, so await, streams and Promise combinators suspend on WASI 0.3 waitables and resume from host callbacks. Conformance contracts run the same programs under Node.js and Wasmtime, with fuel and memory limits, and compare the results (see Conformance).