benoitc/erlang_wasm
68.4
Adequate · 2 October 2026
51.7k
lines of production code
Erlang
primary language
2
measurements over time
What this system is
This system is an Erlang-based WebAssembly runtime that executes tenant scripts via a language-neutral worker kernel supporting QuickJS, CPython, and Lua. It provides comprehensive WASI 0.2 capabilities, including HTTP communication, file system access, and socket networking, while ensuring security through hardened native backends and strict sandboxing. The architecture emphasizes performance and reliability through snapshot-based instance management, granular memory tracking, and robust resource cleanup mechanisms.
Features
Add build and verification scripts for WebAssembly test fixtures
Added a suite of build and verification scripts to generate and validate the WebAssembly test fixtures used by the integration and conformance suites. The new \scripts/build-component-fixture.sh\ builds component-model test cases (including WASI 0.2 worlds like clocks, sockets, and filesystems) targeting \wasm32-unknown-unknown\ and \wasm32-wasip2\. Language-specific reactor fixtures for Lua, QuickJS, and Python are now built via \scripts/build-lua-reactor.sh\, \scripts/build-quickjs-reactor.sh\, and \scripts/build-python-reactor.sh\, which compile the interpreters as \init()/handle()\ reactors using WASI SDK 34. Additional scripts handle fetching pre-built Python artifacts (\fetch-python-fixture.sh\), extracting CPython link lines (\python-link-line.sh\), building wasmtime's native WASI 0.2 test programs (\build-wasmtime-p2.sh\), and verifying fixture checksums (\verify-fixtures.sh\).
scripts · high confidence
Introduce WASI 0.2 HTTP support with pluggable transports
Components can now make outbound HTTP requests and host HTTP reactors using the WASI 0.2 \wasi:http\ interface. The implementation provides a pluggable transport layer, defaulting to HTTP/1.1 (\wasi\_http\_h1\) but also supporting HTTP/2 (\wasi\_http\_h2\), allowing guests to perform requests over granted network authorities with configurable TLS and timeouts. Additionally, a new HTTP listener (\wasi\_http\_listener\) enables hosting \wasi:http\ reactor components, translating incoming HTTP requests into component handles and returning responses.
src · high confidence
Introduce language-neutral worker kernel for script execution
Added a new execution bootstrap (\script\_v1\) that provides a consistent interface for running tenant scripts in both QuickJS and CPython environments. This kernel enforces a strict contract where tenants define a single \main(context)\ entry point, ensuring safe, streaming output via a delimiter marker rather than buffered stdout. It handles context loading from \/context.json\, manages error framing for non-serializable results or missing entry points, and isolates execution by loading tenant modules by explicit path to prevent access to host modules.
priv · high confidence
New WASM worker adapters and cleanup infrastructure
This change introduces a new worker subsystem in \src/worker\ featuring adapters for JavaScript (both command and reactor modes), Python (reactor mode), and Lua, enabling execution of these languages via WebAssembly snapshots. It also adds a robust cleanup management system, including a node-wide cleanup manager, per-request cleanup stewards, and a dynamic supervisor, to handle resource teardown and state recovery reliably. Additionally, a comprehensive conformance test suite is provided to validate adapter behavior against the kernel's acceptance rules.
src/worker · high confidence
New benchmark harnesses for JIT adoption, allocation, and request latency
Added a suite of new benchmark modules in \bench/paths\ to measure specific performance characteristics of the WASM runtime. \adopt.erl\ verifies whether a second instance can adopt compiled code raised by a first, one-call guest. \allocwords.erl\ provides a per-process heap allocation estimator using GC trace events, replacing node-wide statistics. \compileheap.erl\ compares memory usage across OTP, inline, and child compiler processes. \guestarm.erl\ measures the cost of a single guest request startup. \phasing\_adapter.erl\ times the five adapter boundaries of a worker request. \pyarms.erl\ profiles four CPython execution configurations (cold, pre-lowered, whole, adopted). \reqbench.erl\ drives a pool of script workers to measure throughput and queue depths. \restorebits.erl\ isolates the time spent in \wasm:restore/3\ components (new, alloc, fill, runs).
bench · high confidence
Behavioural changes
Documentation overhaul and new WASI 0.2 interop fixtures
The project now includes \AGENTS.md\ and \CLAUDE.md\ to guide AI coding agents, and the \README\ has been restructured with a task-oriented 'Where to start' table and a new documentation index. The \rebar.config\ has been updated to include \h1\ and \h2\ dependencies for WASI HTTP support, and the documentation build now includes a new set of runnable examples and guides. Additionally, new fixture directories for wasmtime p2 interop tests have been added to \.gitignore\.
(repo-wide) · high confidence
Hardened WASI file backend against escapes and DoS
The native WASI file backend now prevents path-escape vulnerabilities and directory-read denial-of-service attacks. Symlink resolution for stat and set-times operations is performed internally with strict depth and budget limits, ensuring that relative symlinks cannot traverse outside the preopened sandbox. Directory listings are optimized by lazily opening and reusing a duplicated file descriptor, avoiding costly rescans on every read call.
_c\src · high confidence
Renamed script\_worker to qjs\_worker to clarify its role as a baseline interpreter
The example module previously named \script\_worker\ has been renamed to \qjs\_worker\ to better reflect that it is a specific implementation using QuickJS rather than a generic script runner. This change updates the module name, documentation references, and temporary file prefixes throughout the example code. The commit notes that this module now serves as the unchanged baseline against which a new language-neutral worker kernel is measured, distinguishing the specific JavaScript interpreter from the broader kernel concept.
examples · high confidence
Snapshot support and memory tracking refinements
The system now supports capturing and restoring WebAssembly instances via a new snapshotting mechanism. This introduces a node-wide byte-budget counter for snapshots, managed via persistent terms with versioning to ensure safety across upgrades. Instance records now track snapshot state (open, capturing, destroying) and reader counts using atomics, alongside a \module\_handle\ to preserve provenance for cached modules. Additionally, memory tracking has been refined by replacing the \MEM\_SIZE\ index with a new \MEM\_DIRTY\ index, allowing for more granular tracking of memory changes during snapshot operations.
include · high confidence
Test coverage
Add WASI 0.2 component fixtures and property tests for the Canonical ABI; Added test fixtures and documentation for Lua, CPython, and QuickJS language runtimes; Added test fixtures for WASI 0.2 compliance testing; Added test fixtures for composed Wasm components; Added test support adapters for WASI and component runtime verification; Added tests for composed counter components; Expanded component-model test fixtures for WASI 0.2 and Canonical ABI validation.
Dependencies
Add component test fixtures using wit-bindgen 0.62
Added a suite of new test fixtures under test/fixtures/component/ (including asyncimp, asyncval, counter, echo, wasifs, wasisock, and others) to support testing the WebAssembly Component Model. These Rust-based fixtures depend on wit-bindgen version 0.62 (or wit-bindgen-rt 0.44.0 for composed components) and are configured as cdylib crates or binaries, providing the necessary code generation bindings for WASI interfaces and component composition scenarios.
(dependencies) · high confidence
Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.
How this codebase got here
Score
- CAI 74 → 68 (-6.1)
- Rubric changed (rubric-2026.09.12 → rubric-2026.09.18) — scores are not directly comparable.
Lenses
- Code Health 86 → 85 (-0.8)
- Architecture 100 → 84 (-16.3)
- Maturity 61 → 61 (+0.3)
- Readiness 78 → 59 (-18.7)
- Security 100 → 100 (+0.0)
- Event Sourcing 100 → 100 (+0.0)
- Performance 100 (new)
Resolved (35)
- Coverage not measured — no coverage collector is wired up
- Duplicated block (10–13 lines × 3) (examples/lua_reactor_adapter.erl)
- Duplicated block (12 lines × 2) (examples/py_adapter.erl)
- Duplicated block (12 lines × 3) (examples/lua_reactor_adapter.erl)
- Duplicated block (4–5 lines × 5) (examples/lua_reactor_adapter.erl)
- Duplicated block (5 lines × 2) (examples/lua_reactor_adapter.erl)
- Duplicated block (5 lines × 2) (examples/py_adapter.erl)
- Duplicated block (5 lines × 4) (examples/lua_reactor_adapter.erl)
- Duplicated block (6 lines × 2) (examples/py_adapter.erl)
- Duplicated block (6 lines × 3) (examples/lua_reactor_adapter.erl)
- Duplicated block (6 lines × 3) (examples/lua_reactor_adapter.erl)
- Duplicated block (6 lines × 5) (examples/lua_reactor_adapter.erl)
- Duplicated block (7 lines × 2) (examples/lua_reactor_adapter.erl)
- Duplicated block (7–9 lines × 2) (examples/lua_reactor_adapter.erl)
- Duplicated block (8 lines × 2) (examples/py_adapter.erl)
- Duplicated block (8 lines × 3) (examples/lua_reactor_adapter.erl)
- Duplicated block (8–10 lines × 2) (examples/qjs_adapter.erl)
- Duplicated block (8–10 lines × 3) (examples/py_adapter.erl)
- Duplicated block (9 lines × 2) (examples/lua_reactor_adapter.erl)
- Duplicated block (9 lines × 2) (examples/py_adapter.erl)
- …and 15 more
New (68)
- Documentation: contradicts the code (docs/architecture.md)
- Documentation: contradicts the code (docs/compiled-tier.md)
- Documentation: contradicts the code (docs/features.md)
- Documentation: no project overview (README.md)
- Duplicated block (10 lines × 2) (scripts/build-snapshot-fixtures.py)
- Duplicated block (10–13 lines × 2) (src/worker/wasm_javascript.erl)
- Duplicated block (12 lines × 2) (src/worker/wasm_javascript_command.erl)
- Duplicated block (12 lines × 3) (src/worker/wasm_javascript.erl)
- Duplicated block (3–9 lines × 5) (scripts/build-snapshot-fixtures.py)
- Duplicated block (4–5 lines × 5) (src/worker/wasm_javascript.erl)
- Duplicated block (5 lines × 2) (src/wasi_fs.erl)
- Duplicated block (5 lines × 2) (src/wasi_preview2.erl)
- Duplicated block (5 lines × 2) (src/wasm_component_link.erl)
- Duplicated block (5 lines × 2) (src/worker/wasm_javascript_command.erl)
- Duplicated block (5 lines × 2) (src/worker/wasm_lua.erl)
- Duplicated block (5 lines × 4) (src/worker/wasm_javascript_command.erl)
- Duplicated block (6 lines × 2) (bench/paths/workerbench.erl)
- Duplicated block (6 lines × 2) (scripts/build-snapshot-fixtures.py)
- Duplicated block (6 lines × 2) (scripts/build-snapshot-fixtures.py)
- Duplicated block (6 lines × 2) (src/wasi_http.erl)
- …and 48 more
Changes since last survey
- 241 commits — 238 feature/other, 3 fixes
By area
- test/fixtures — 36 commits
- (root) — 32 commits
- src/wasi_preview2.erl — 27 commits
- src/worker — 26 commits
- (repo) — 25 commits
- bench/paths — 11 commits
- docs/architecture.md — 9 commits
- test/audit — 8 commits
- test/support — 8 commits
- src/wasm_canon.erl — 6 commits
- src/wasi_http.erl — 5 commits
- src/wasm_component.erl — 5 commits
- src/wasm.erl — 3 commits
- src/wasm_component_link.erl — 3 commits
- c_src/wasi_file_nif.c — 2 commits
- docs/examples — 2 commits
- docs/getting-started.md — 2 commits
- docs/javascript.md — 2 commits
- docs/worker-reference.md — 2 commits
- src/wasi_fs.erl — 2 commits
Notable commits
- fix: Fix directory and zero-length reads on descriptor streams
- fix: Label every code block, and fix the ones that were not code
- fix: Merge pull request #40 from benoitc/fix-runner-exit-stall
- change: Accept finish past the operation ceiling
- change: Add a Component Model guide
- change: Add a user layer: concepts, a path in, and ten runnable examples
- change: Add a writable wasi:filesystem, over the same sandbox (Phase 2)
- change: Add an entry mode to wasm_python
- change: Add reqbench: a worker pool under many callers, with its queues
- change: Add restore_ahead: restore the next instance while the worker waits
- change: Add the Phase 0 component-model fixture
- change: Add the cleanup manager and steward supervision
- change: Add the cleanup steward fault-injection seam
- change: Add the wasi:http outbound path over h1
- change: Add the wasmtime p2 interop track and an opt-in network grant
- change: Assert the entered count for every arm ordering
- change: Authenticate cleanup operations by the steward that reserved them
- change: Await an async host import that completes at once
- change: Bound WASI 0.2 clock waits and report failed stream writes
- change: Bound request startup by the request's own deadline
- …and 221 more
Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.
Survey your own repository
benoitc/erlang_wasm was measured the same way every project in this corpus was: the same rubric, at a pinned commit, with the result published in full. Point a surveyor at a repository you know and see whether you agree with it.
About this page
- The score is its most recent published measurement, taken on 2 October 2026 at a pinned commit. It is not a live figure and does not change until the project is measured again.
- Measured at commit 68ba50460158b670d8827fccaf6589b1efe92017 — the exact code this score is about.
- Scored under rubric-2026.09.18 — the same rubric and the same method as every other entry in this index.
- Measured by watchdog.canine.dev using codehealth-analyzer preprod-e569280dd5e2.