Progress log and benchmarks for Almide's JS/TS-friendly WASM SDK story.
The actual binding generator lives at almide-wasm-bindgen (written in Almide); this repo tracks the vision, iteration snapshots, and head-to-head measurements.
See JS_TS_FRIENDLY_VISION.md (in the top-level almide/ repo) for the checkbox-level status. High-level summary as of iter 58:
- P1 (Parity floor): 8 / 8 ✅
- P2 (Leapfrog): 5 / 7, remaining items are
Matrix[T]dtype (iter 60+) and effect visibility refinements - P3 (Frontier): P3-2 WIT emission ✅; Component Model and async under investigation
# Install almide (once)
curl -fsSL https://almide.dev/install.sh | sh
# Write a matrix library in Almide
cat > mylib.almd <<'EOF'
pub fn axpy(a: Matrix, b: Matrix, ka: Float, kb: Float) -> Matrix =
matrix.add(matrix.scale(a, ka), matrix.scale(b, kb))
EOF
# One command to .wasm + ESM + .d.ts + .wit + package.json, wasm-opt'd
almide run src/main.almd -- --target wasm --outdir dist mylib.almd # from almide-landerThen in TypeScript:
import init, { axpy, Matrix } from "./dist/mylib.js";
await init();
const A = { rows: 512, cols: 512, data: ... };
const B = { rows: 512, cols: 512, data: ... };
const out = axpy(A, B, 2.0, 3.0); // out is a Matrix handle
console.log(out.rows, out.cols); // 512 512
console.log(out.data); // Float64Array (zero-copy view over WASM memory)| Workload | Almide | Rust+wasm-bindgen | Result |
|---|---|---|---|
| matmul 256×256 | 4.6 ms | 8.5 ms | Almide 1.84× faster |
| axpy N=512 (a·ka + b·kb) | 0.38 ms | 0.36 ms | Rust 1.05× narrow |
| compose N=512 (3-term) | 0.58 ms | 0.44 ms | Rust 1.31× |
| binary size | 1490 B | 11225 B | Almide 7.53× smaller |
Reproduction: _progress/0058-rust-comparison-rerun.md.
| Almide | TypeScript |
|---|---|
Int / Float / Bool |
number / number / boolean |
String |
string (UTF-8) |
Unit |
void |
List[T] |
T[] |
Option[T] |
T | null |
Result[T, String] |
T (Err is thrown) |
effect fn |
T with JSDoc @throws |
Record { ... } |
interface |
Variant { A, B(Int) } |
{ tag: "A" } | { tag: "B", _0: number } |
Tuple[T1, T2, ...] |
[T1, T2, ...] |
Matrix |
class Matrix (persistent handle, .data zero-copy) |
Map[K, V] |
Map<K, V> (K/V arbitrary including nested) |
Set[T] |
Set<T> |
Bytes |
Uint8Array |
Nested composition works through: Map<string, Person>, List<Map<string, number[]>>, Record { matrix: Matrix, labels: string[] }, etc.
Same compiled .wasm runs in:
- Node ✅ / Bun ✅ / Deno ✅
- Browser ✅ (fetch +
WebAssembly.instantiate) - wasmtime CLI ✅ (WASI
fd_writeshim) - wasmtime-py ✅ (WASI bindings)
- Cloudflare Workers 🟡 (structurally compatible, not yet runtime-verified)
Harness: examples/multihost_harness.sh.
Each loop iteration lands one checkbox and drops a file in _progress/. The index in _progress/README.md is the fastest way to trace how a capability landed.
- almide — the language + pure-Rust compiler
- almide-wasm-bindgen — JS/TS binding generator (this README's subject)
- almide-bindgen — native FFI generator (21 languages via cdylib)
- almide-lander — CLI orchestrator (
--target wasm→ npm-publishable dist/)