WebAssembly (Wasm) adalah format instruksi biner untuk mesin virtual berbasis stack. File .wasm berisi deretan byte yang artinya instruksi kecil seperti "ambil angka ini", "kalikan dua angka teratas". Browser menerjemahkan instruksi itu ke kode mesin CPU-mu, lalu menjalankannya di dalam sandbox. Bayangin dapur Homestay Kabut, homestay kecil milik Bu Sri di Dieng. Juru masaknya (Wasm) bekerja cepat dengan resep yang ditulis dalam kode standar yang dimengerti dapur mana pun, tapi dia gak pernah keluar ke ruang tamu. Yang melayani tamu (halaman, klik, jaringan) tetap resepsionis, yaitu JavaScript. Juru masak cuma memakai bahan yang diserahkan resepsionis lewat jendela dapur.
🧪 Tebakan cepat: bisakah modul Wasm langsung menulis "Rp 700.000" ke halaman, tanpa bantuan JavaScript sama sekali? Tebak dulu, jawabannya ada di bagian "Yang bukan Wasm".
Contoh sepanjang jalur ini: Homestay Kabut
Bu Sri punya tiga kamar: Kamar Teras Rp 350.000 semalam, Kamar Loteng Rp 275.000, dan Kamar Kebun Rp 425.000. Sepanjang jalur WebAssembly kita mengerjakan dua hal untuknya:
- Fungsi pertama: harga menginap, yaitu
malam × harga per malam. Kamar Teras 2 malam = 2 × 350.000 = 700.000. Kita tulis dalam Wasm, lalu nanti dalam Rust dan Go. - Pekerjaan beratnya: foto kamar. Bu Sri mengunggah foto kamar 1200 × 800 piksel. Di browser, foto itu dijadikan abu-abu (grayscale), diperkecil, dan diberi blur. Kita kerjakan dulu dengan JavaScript, lalu dengan Wasm, dan kita ukur dengan jujur mana yang lebih cepat.
Wasm itu apa
Tiga kata di definisinya punya arti yang jelas:
- Biner: isinya byte, bukan teks. Fungsi harga menginap, setelah dirakit, cuma 47 byte.
- Format instruksi: tiap byte (atau beberapa byte) adalah satu instruksi. Byte
6cartinyai32.mul: kalikan dua bilangan bulat 32-bit. - Mesin berbasis stack: instruksinya mengambil angka dari tumpukan (stack) dan menaruh hasilnya kembali di sana. Gak ada variabel register seperti di CPU asli.
Begini hargaInap(2, 350000) dijalankan:
| Instruksi | Artinya | Isi stack sesudahnya |
|---|---|---|
local.get 0 |
ambil parameter pertama (malam) | [2] |
local.get 1 |
ambil parameter kedua (harga per malam) | [2, 350000] |
i32.mul |
ambil dua angka teratas, kalikan | [700000] |
Angka yang tersisa di stack, 700.000, jadi nilai kembalian fungsinya. Tipe angkanya tetap dan sedikit: i32 dan i64 (bilangan bulat 32 dan 64 bit), f32 dan f64 (pecahan). Wasm jarang ditulis langsung. Biasanya dia hasil compile dari bahasa lain: C dan C++ (lewat Emscripten), Rust, Go, atau AssemblyScript.
Dari kode ke browser
Jalannya selalu sama: kode sumber, lalu compiler membuat file .wasm, lalu browser membaca byte-nya, memeriksa (validasi), meng-compile-nya ke kode mesin CPU-mu, dan menjalankannya. Dari JavaScript, kamu memuat dan memanggilnya begini:
// 47 byte hasil wat2wasm dari harga.wat (dibedah di pelajaran "Wasm Hello World")
const bytes = new Uint8Array([
0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x01, 0x07, 0x01, 0x60,
0x02, 0x7f, 0x7f, 0x01, 0x7f, 0x03, 0x02, 0x01, 0x00, 0x07, 0x0d, 0x01,
0x09, 0x68, 0x61, 0x72, 0x67, 0x61, 0x49, 0x6e, 0x61, 0x70, 0x00, 0x00,
0x0a, 0x09, 0x01, 0x07, 0x00, 0x20, 0x00, 0x20, 0x01, 0x6c, 0x0b,
]);
WebAssembly.instantiate(bytes).then(({ instance }) => {
const { hargaInap } = instance.exports;
console.log(hargaInap(2, 350000)); // 700000: Kamar Teras, 2 malam
});
new Uint8Array([...])adalah isi file.wasm. Biasanya byte ini diambil denganfetch, di sini ditulis langsung supaya bisa jalan di mana saja.WebAssembly.instantiate(bytes)meng-compile byte-nya lalu membuat instance, yaitu modul yang siap dipakai. Hasilnya Promise.instance.exportsberisi fungsi yang modulnya bagikan ke luar (export).hargaInapdipanggil seperti fungsi JavaScript biasa.- Untuk modul kecil seperti ini ada juga versi sinkronnya, tanpa Promise:
new WebAssembly.Instance(new WebAssembly.Module(bytes), imports)langsung memberiinstanceyang sama.
Kenapa Wasm bisa lebih cepat untuk tugas tertentu? Dia sudah di-compile jadi format biner yang dekat dengan kode mesin, dan tipe tiap angka sudah pasti. Browser gak perlu mem-parse teks dan gak perlu menebak tipe seperti saat menjalankan JavaScript. Browser tetap meng-compile byte Wasm ke kode mesin (V8 di Chrome memakai compiler cepat Liftoff dulu, lalu TurboFan untuk fungsi yang sering dipanggil), tapi hasilnya lebih bisa ditebak, dan untuk hitungan berat kecepatannya mendekati program native. Untuk pekerjaan ringan, JavaScript sama cepatnya. Pelajaran berikutnya mengukurnya.
Yang bukan Wasm
- Bukan pengganti JavaScript. JavaScript tetap mengurus halaman, klik, dan jaringan. Wasm mengurus hitungan berat.
- Gak bisa menyentuh DOM langsung. Wasm gak kenal
document,fetch, ataulocalStorage. Dia cuma bisa memanggil fungsi yang JavaScript serahkan sebagai import. - Bukan plugin seperti Flash. Wasm bawaan browser, jalan di sandbox yang sama dengan JavaScript, dengan aturan keamanan yang sama.
- Gak otomatis lebih cepat. Memanggilnya dan menyalin data ke dalamnya ada ongkosnya.
Ini modul yang minta satu fungsi dari JavaScript untuk menampilkan total:
// impor.wat berisi: (import "halaman" "tampilkan" (func $tampilkan (param i32)))
WebAssembly.instantiate(imporBytes, {
halaman: {
tampilkan: (total) => {
console.log('Total: Rp ' + total.toLocaleString('id-ID')); // JS yang menulis
},
},
}).then(({ instance }) => {
const { pesan } = instance.exports;
pesan(2, 350000); // Total: Rp 700.000
});
Wasm menghitung 700.000 lalu memanggil tampilkan. Yang menulis ke console atau ke halaman tetap JavaScript. Jadi jawaban tebakannya: gak bisa. Lupa memberi objek import-nya, dan Chrome 147 menolak sebelum apa pun jalan: TypeError: WebAssembly.instantiate(): Imports argument must be present and must be an object.
Di mana Wasm jalan
- Browser: Chrome 57 dan Firefox 52 (Maret 2017), Safari 11 (September 2017), Edge 16 (Oktober 2017), dan semua versi sesudahnya.
- Node.js: objek
WebAssemblyyang sama tersedia sejak Node 8. - Server dan terminal: runtime seperti Wasmtime menjalankan
.wasmdi luar browser, dengan WASI sebagai pintu ke file dan jam sistem. - Edge: platform seperti Cloudflare Workers menjalankan Wasm dekat dengan pengguna.
File .wasm yang sama jalan di semua tempat itu. Tiap mesin meng-compile-nya ke CPU-nya sendiri (x86-64, ARM64), asalkan import yang diminta modul tersedia.
Siapa yang memakainya
- Figma: editor desainnya ditulis dalam C++ dan di-compile ke Wasm. Waktu muatnya jadi lebih dari 3 kali lebih cepat (blog Figma, Juni 2017).
- Adobe Photoshop versi web: kode C++ Photoshop dibawa ke browser lewat Emscripten dan Wasm (web.dev, 2021).
- Google Sheets: mesin hitung rumusnya ditulis dalam Java dan di-compile ke WasmGC, sekitar 2 kali lebih cepat dari versi JavaScript sebelumnya (web.dev, 2024).
Polanya sama: aplikasinya sudah punya kode besar di bahasa lain, atau butuh hitungan berat yang stabil.
📌 Standarnya: W3C dan versi 1.0, 2.0, 3.0
- 1.0 jadi W3C Recommendation pada 5 Desember 2019, satu-satunya versi yang berstatus Recommendation. Isinya fungsi, empat tipe angka, memori linear, dan tabel.
- 2.0 menambahkan instruksi sign-extension, konversi float ke int tanpa trap, fungsi dengan banyak nilai kembalian (multi-value), reference types, instruksi tabel dan banyak tabel, operasi memori massal (bulk memory), dan instruksi vektor 128-bit (SIMD).
- 3.0 diumumkan 17 September 2025 sebagai standar "live" yang baru. Isinya: ekspresi konstanta yang diperluas, tail call, exception handling, banyak memori, alamat 64-bit (memory64), typed references, garbage collection (WasmGC), instruksi vektor relaxed, profil deterministik, dan custom annotations. Di sisi JavaScript ada JS string builtins.
Dokumen W3C terbarunya (9 Oktober 2026) menjelaskan rilis 3.0 dan berstatus Candidate Recommendation Draft. Working Group-nya sengaja menjaganya sebagai standar hidup di status itu, gak dinaikkan ke Recommendation. Fitur mana yang sudah jalan di browser mana bisa dicek di webassembly.org/features.
⚠️ Jebakan yang sering ketemu
- Mengira Wasm pasti lebih cepat. Fungsi kecil yang dipanggil ribuan kali dari JavaScript bisa lebih lambat dari JavaScript biasa. Ukur dulu.
- Mengira Wasm bisa memegang halaman. Semua urusan DOM,
fetch, dan penyimpanan lewat JavaScript, sebagai import. - Lupa objek import. Modul yang minta import gak mau dibuat tanpa objeknya:
TypeErrorsebelum satu instruksi pun jalan. - Angka i32 meluap diam-diam.
hargaInap(7000, 350000)seharusnya 2.450.000.000, tapi i32 cuma muat sampai 2.147.483.647. Hasilnya-1844967296, tanpa error.
TL;DR: WebAssembly adalah format instruksi biner untuk mesin virtual berbasis stack: byte-nya diterjemahkan browser ke kode mesin dan dijalankan di sandbox. Biasanya hasil compile dari C/C++, Rust, atau Go. Kamu memuatnya dengan WebAssembly.instantiate(bytes) dan memanggil fungsi di instance.exports. Wasm bukan pengganti JavaScript dan gak bisa menyentuh DOM: dia cuma bisa memanggil fungsi yang JavaScript berikan sebagai import. Jalan di semua browser modern sejak 2017, di Node, di Wasmtime, dan di edge. Dipakai Figma, Photoshop web, dan Google Sheets. Standar 1.0 jadi W3C Recommendation tahun 2019, 2.0 menambah SIMD dan reference types, 3.0 (2025) menambah GC, memory64, exception handling, dan tail call. Contoh sepanjang jalur ini: harga menginap Homestay Kabut (Kamar Teras 2 malam = 700.000) dan foto kamar Bu Sri yang diproses di browser.