WebAssembly 2.0 Complete Overview - Web Development Transformed by GC Integration and Component Model

2025.12.02

WebAssembly (Wasm) has been leading the web performance revolution since its release in 2017. And from 2024 to 2025, a series of new features called WebAssembly 2.0 have become available in major browsers. This article explains the revolutionary features of WebAssembly 2.0 that developers should know about and how to use them in practice.

What is WebAssembly 2.0

WebAssembly 2.0 is not a single release, but a collective term for the following major specification extensions.

FeatureStatusMain Use
GC (Garbage Collection)Phase 4 CompleteNative support for high-level languages
Component ModelPhase 3Inter-module coordination, cross-language interop
WASI Preview 2StableServer-side, edge execution
Exception HandlingPhase 4 CompleteNative try-catch syntax support
Tail CallPhase 4 CompleteFunctional language optimization

Garbage Collection (WasmGC)

Why GC Integration is Important

Traditional WebAssembly required manual memory management on linear memory. While this was suitable for C/C++ and Rust, high-level languages like Java, Kotlin, Dart, and Python needed to bundle their own GC runtime into Wasm.

flowchart TB
    subgraph Before["Previous Problem"]
        App1["Kotlin/Wasm Application"]
        GC1["Kotlin GC Runtime (~500KB added)<br/>← Each language brings its own GC"]
        Mem1["WebAssembly Linear Memory"]
        App1 --> GC1 --> Mem1
    end

    subgraph After["After WasmGC"]
        App2["Kotlin/Wasm Application"]
        GC2["Browser Built-in GC (V8/SpiderMonkey)<br/>← Direct use of browser GC"]
        App2 --> GC2
    end

Actual Effects of WasmGC

According to benchmarks published by the Google Sheets team, the following improvements were achieved with migration to WasmGC.

  • Binary Size: ~50% reduction compared to before
  • Startup Time: 2x+ faster
  • Memory Usage: 30-40% reduction at peak

Supported Languages and Compilers

// List of WasmGC-supported languages (as of January 2025)
const wasmGCLanguages = {
  production: [
    "Kotlin/Wasm",      // Official JetBrains support
    "Dart/Flutter",     // Official Google, Flutter Web
    "Java (TeaVM)",     // TeaVM 0.10+
  ],
  experimental: [
    "OCaml",            // wasocaml
    "Scheme",           // Hoot
    "Go",               // go-wasm (experimental)
  ],
  planned: [
    "Python",           // Pyodide successor
    "Ruby",             // Under consideration
  ]
};

Component Model

Revolution in Cross-Language Interoperability

The Component Model is a mechanism for type-safe coordination between Wasm modules written in different languages.

flowchart TB
    subgraph Component["WebAssembly Component"]
        subgraph Modules["Modules"]
            Rust["Rust Module<br/>(Image Proc)"]
            Python["Python Module<br/>(ML Inference)"]
            JS["JS Module<br/>(UI)"]
        end
        WIT["WIT (WebAssembly Interface Types)<br/>Type Definitions & Interfaces"]

        Rust --> WIT
        Python --> WIT
        JS --> WIT
    end

WIT (WebAssembly Interface Types)

WIT is a language for defining interfaces between components.

// image-processor.wit
package myapp:image-processor@1.0.0;

interface image-ops {
    record image {
        width: u32,
        height: u32,
        data: list,
    }

    record resize-options {
        target-width: u32,
        target-height: u32,
        quality: option,
    }

    resize: func(img: image, opts: resize-options) -> image;
    apply-filter: func(img: image, filter-name: string) -> image;
}

world image-processor {
    export image-ops;
}

Practical: Creating a Rust Component

// Cargo.toml
// [dependencies]
// wit-bindgen = "0.25"

use wit_bindgen::generate;

generate!({
    world: "image-processor",
    exports: {
        "myapp:image-processor/image-ops": ImageProcessor,
    }
});

struct ImageProcessor;

impl exports::myapp::image_processor::image_ops::Guest for ImageProcessor {
    fn resize(img: Image, opts: ResizeOptions) -> Image {
        // High-performance image resize processing
        let resized = image::imageops::resize(
            &img.to_dynamic_image(),
            opts.target_width,
            opts.target_height,
            image::imageops::FilterType::Lanczos3,
        );
        Image::from_dynamic_image(resized)
    }

    fn apply_filter(img: Image, filter_name: String) -> Image {
        match filter_name.as_str() {
            "grayscale" => img.grayscale(),
            "blur" => img.blur(2.0),
            _ => img,
        }
    }
}

WASI Preview 2

Standardization of Server-Side WebAssembly

WASI (WebAssembly System Interface) Preview 2 standardizes the Wasm execution environment outside of browsers.

WASI Preview 2 Main Interfaces:
├── wasi:io          # Streams, Polling
├── wasi:clocks      # Time, Timers
├── wasi:random      # Random number generation
├── wasi:filesystem  # Filesystem access
├── wasi:sockets     # TCP/UDP sockets
├── wasi:http        # HTTP client/server
└── wasi:cli         # Command line args, environment variables

Usage in Edge Computing

Major edge platforms like Cloudflare Workers, Fastly Compute, and Vercel Edge support WASI.

// WASI HTTP Handler example (Rust)
use wasi::http::types::{IncomingRequest, ResponseOutparam};

#[export_name = "wasi:http/incoming-handler@0.2.0#handle"]
pub fn handle(request: IncomingRequest, response_out: ResponseOutparam) {
    let path = request.path_with_query().unwrap_or_default();

    let (status, body) = match path.as_str() {
        "/api/hello" => (200, "Hello from WASI!"),
        "/api/time" => {
            let now = wasi::clocks::wall_clock::now();
            (200, format!("Current time: {:?}", now))
        }
        _ => (404, "Not Found"),
    };

    let response = OutgoingResponse::new(status);
    response.body().unwrap().write_all(body.as_bytes());
    ResponseOutparam::set(response_out, Ok(response));
}

Exception Handling

Native Exception Support

Previously in Wasm, exception handling needed to be done at the JavaScript boundary or through error code-based processing. With the Exception Handling proposal, language-native exception mechanisms are now supported.

// Exception handling in C++ (Emscripten)
#include <emscripten.h>
#include <stdexcept>

EMSCRIPTEN_KEEPALIVE
int divide(int a, int b) {
    if (b == 0) {
        throw std::invalid_argument("Division by zero");
    }
    return a / b;
}
// Calling from JavaScript
try {
    const result = Module._divide(10, 0);
} catch (e) {
    // Can now directly catch Wasm exceptions
    console.error("Caught Wasm exception:", e.message);
}

Performance Comparison

Benchmark Results (January 2025)

BenchmarkJavaScriptWasm 1.0Wasm 2.0 (GC)
JSON Parse100ms45ms42ms
Image Filter850ms120ms115ms
Kotlin Hello World Startup-380ms95ms
Dart App Init-520ms180ms

Note: For GC-integrated languages (Kotlin, Dart), startup time is significantly improved. This is because browser built-in GC optimizations are applied.

Getting Started Now

Development Environment Setup

# Rust + WebAssembly component development
rustup target add wasm32-wasip2
cargo install cargo-component

# Create new project
cargo component new my-wasm-component
cd my-wasm-component

# Build
cargo component build --release

Browser Compatibility

FeatureChromeFirefoxSafariEdge
WasmGC119+120+18.2+119+
Exception Handling95+100+15.2+95+
Tail Call112+121+-112+
SIMD91+89+16.4+91+

Summary

WebAssembly 2.0 is a technological innovation that greatly expands the possibilities of the web platform.

  • WasmGC: First-class support for high-level languages
  • Component Model: Enabling cross-language interoperability
  • WASI Preview 2: Standardization of server-side/edge

With these features, WebAssembly’s vision of “any language, runs anywhere” is becoming a reality. The importance of Wasm in future web development is expected to increase further.

← Back to list