๐Ÿ†

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