🏆

Making WASM a First-Class Language on the Web

Component Model: Calling Web APIs Directly Without JS Glue

Explores the current problem of WebAssembly being treated as a second-class citizen on the web, and how Mozilla's Component Model aims to solve it.

Architecture Diagram

Before vs After
Now: WASM = Second-class Citizen
📝
Rust / C++
→
📦
.wasm
→
⚡
JS Glue Code
embind / wasm-bindgen
→
🌐
Web API
-45% performance
Future: Component Model = First-class Citizen
📝
Rust / C++
→
🧩
Component (.wasm)
Includes WIT interface
→
🌐
Direct Web API calls
No JS glue needed!
WIT Interface Example
WIT Declaration:
component {
  import std:web/console;
}
Usage in Rust:
use std_web::console;
console::log("hello, world");
Standardization Timeline
2017 WASM Launch → Now: Mozilla + Google standardizing → Experimental: Jco, Wasmtime → Future: Browser native support (years away)

How It Works

1

Current: WASM requires manual loading via JS APIs like WebAssembly.instantiateStreaming()

2

Current: No direct access to DOM, console, or Web APIs — JS glue code serves as bridge

3

Current: Each language needs separate binding tools, rustc --target=wasm output doesn't run directly in browsers

4

Component Model: Declare needed Web APIs with WIT (Interface Description Language)

5

Component Model: Browser loads directly via <script type="module" src="component.wasm">

6

Component Model: Hybrid usage from JS via import { fn } from "lib.wasm"

7

Result: Complete JS glue code elimination → 45% performance overhead resolved, unified toolchain

Pros

  • ✓ Complete JS glue code elimination — 45% DOM performance overhead resolved
  • ✓ Load WASM directly via <script> tag just like JS
  • ✓ Unified toolchain per language — run directly in browser from standard compiler
  • ✓ Type-safe Web API interface declarations with WIT
  • ✓ Hybrid usage with JS possible — gradual adoption
  • ✓ Runs outside browser too (Wasmtime) — reuse web and server code

Cons

  • ✗ Still under standardization — too early for production use
  • ✗ Frequent spec changes cause tooling churn
  • ✗ Difficult polyfill/feature detection — may lose JS bridge flexibility
  • ✗ Component Model itself introduces new complexity (WIT learning curve)
  • ✗ JS shim cost already negligible for WebGL2/WebGPU
  • ✗ Memory management unresolved — unclear if Wasm GC proposal is needed for DOM references

Use Cases

DOM-intensive WASM apps — direct DOM manipulation without glue Rust/C++ web frameworks operating independently without JS Multi-language component composition — Rust image processing + Go networking + JS UI Alternative to mobile OS lock-in — native app-level web apps Component reuse ecosystem via WASM Registry