Mengenal runtime WebAssembly di sisi server: Wasmtime dari Bytecode Alliance, Wasmer, WasmEdge untuk edge/IoT, dan Spin, plus cara embedding runtime dari Rust dengan crate wasmtime dan CLI wasmtime run

Setelah di episode 10 kita memahami WASI dan Component Model — pada episode ini kita bertemu dengan para eksekutornya: runtime WebAssembly di sisi server. Jika di browser engine-nya V8/SpiderMonkey, di server kita memilih runtime sendiri — dan pilihan itu menentukan fitur, performa, dan ekosistem yang kalian dapatkan.
Mengapa runtime penting? Karena runtime adalah "sistem operasi mini" untuk modul Wasm kalian: ia menyediakan WASI, mengelola memory, mengisolasi instance, dan menyediakan API embedding. Memilih runtime yang tepat — dan tahu cara meng-embed-nya — adalah keterampilan inti untuk membangun aplikasi host yang menjalankan plugin Wasm, yang kita lanjutkan di episode 19.
| Runtime | Pengelola | Fokus | Catatan |
|---|---|---|---|
| Wasmtime | Bytecode Alliance | Umum, produksi | Core Project; LTS 36.x (Agu 2025, dukungan s/d Agu 2027) |
| Wasmer | Wasmer Inc. | Umum, komersial | Klaim ~95% kecepatan native; SDK multi-bahasa |
| WasmEdge | CNCF | Edge & IoT | Ringan, startup cepat, cocok embedded |
| Spin | Fermyon (diakuisisi Akamai) | Framework aplikasi | Bukan runtime murni, tapi kerangka app serverless Wasm |
Wasmtime dikembangkan oleh Bytecode Alliance — konsorsium yang juga mengelola WASI dan Component Model — sehingga selalu yang paling cepat mengadopsi spesifikasi terbaru. Ia dirancang untuk embedding: menjadi library di dalam aplikasi host.
Cara termudah mencoba adalah CLI:
curl https://wasmtime.dev/install.sh | bash
wasmtime --versionJalankan komponen WASI:
wasmtime run --dir ./data app.wasmKekuatan Wasmtime ada pada API embedding-nya. Tambahkan dependency:
cargo add wasmtimeKode host paling sederhana:
use anyhow::Result;
use wasmtime::{Engine, Module, Store, Linker};
fn main() -> Result<()> {
let engine = Engine::default();
let module = Module::from_file(&engine, "hello.wasm")?;
let mut store = Store::new(&engine, ());
let linker = Linker::new(&engine);
let instance = linker.instantiate(&mut store, &module)?;
let hello = instance.get_typed_func::<(), ()>(&mut store, "hello")?;
hello.call(&mut store, ())?;
Ok(())
}Engine → kompilasi; Module → bytecode yang dikompilasi; Store → state per instance; Linker → penghubung imports. Empat konsep ini dipakai di hampir semua embedding Wasm, apa pun runtime-nya.
Tip
Module di Wasmtime dikompilasi sekali dan bisa dibuat banyak instance — sangat murah untuk memproses banyak request per detik. Ini pola yang sama dengan caching WebAssembly.Module di browser (episode 13).
Wasmer menjanjikan performa mendekati native (~95%) dan SDK untuk banyak bahasa — Rust, Python, Go, C#, Ruby, dan lainnya — sehingga host tidak harus ditulis dalam Rust. Ia punya sistem package wapm dan mendukung WASI serta WASIX.
curl https://get.wasmer.io -sSfL | sh
wasmer run app.wasmDari Python:
import wasmer
module = wasmer.Module(wasmer.Store(), open("app.wasm", "rb").read())
instance = wasmer.Instance(module)
print(instance.exports.hello())Kekuatan Wasmer ada pada portabilitas embedding — tim yang menulis host dalam Python atau Go tidak perlu belajar Rust.
WasmEdge adalah runtime yang diarahkan untuk edge computing dan perangkat IoT: binary kecil, startup cepat, dan konsumsi memori rendah. Didukung ekosistem CNCF (Cloud Native Computing Foundation) dan sering dipakai sebagai engine FaaS di edge — misalnya di platform yang butuh menjalankan banyak fungsi kecil dengan overhead minimal.
wasmedge --version
wasmedge app.wasmCiri khasnya: dukungan WebAssembly System Interface yang lengkap, integrasi dengan framework AI/ML, dan kemampuannya berjalan di perangkat constrained — topik yang bersinggungan dengan edge functions di episode 12.
Spin bukan sekadar runtime — ini framework aplikasi serverless berbasis Wasm. Kalian menulis handler HTTP, aplikasi menjalankannya di atas runtime Wasmtime, dan Spin mengurus HTTP server, routing, dan state management. Fermyon diakuisisi Akamai, memperkuat posisi Wasm di infrastruktur edge (topik episode 12).
use spin_sdk::http::{IntoResponse, Request, Response, Router};
use spin_sdk::http_component;
#[http_component]
fn handle(req: Request) -> impl IntoResponse {
Router::new()
.get("/hello/:name", |_, ctx| {
let name = ctx.params.get("name").unwrap();
Response::new(200, format!("Halo, {name}!"))
})
.handle(req)
}spin up menjalankan aplikasi ini sebagai service HTTP lokal; ke production, ia di-deploy ke Fermyon Cloud atau SpinKube (Kubernetes) — kita lihat di episode 12.
Aturan praktis pemilihan:
Warning
Jangan menilai runtime hanya dari versi fitur Wasm yang didukung. Periksa juga: kecepatan startup, throughput I/O, dukungan WASI 0.2 vs 0.3, dan model lisensi. Untuk workload produksi, mulailah dengan benchmark yang realistis (episode 15), bukan klaim vendor.
wasm32-wasip1 lama tidak berjalan di runtime yang hanya mendukung WASI 0.2/0.3; rebuild dengan target yang tepat.--dir/--env menentukan akses; modul yang butuh file tapi tidak diberi akses akan gagal di runtime.Module yang sama.Store sendiri; berbagi Store antar thread menyebabkan panic.Pada episode 11 ini, kalian telah mengenal empat runtime utama server-side dan cara meng-embed-nya.
Inti yang harus dibawa pulang:
Di episode 12 selanjutnya kita akan membahas edge functions & serverless (FaaS) — Cloudflare Workers, Fastly Compute, Akamai EdgeWorkers, dan Spin/Kubernetes (SpinKube) — dengan cold start hitungan milidetik, plus pola HTTP handler dan streaming response. Sampai jumpa di episode 12!