WebAssembly in Web Applications
Graphics Rendering (Combining Canvas, WebGL, and WASM)
Canvas 2D Rendering Optimization:
// Using WASM to accelerate Canvas 2D drawing operations
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
// Load WASM module
WebAssembly.instantiateStreaming(fetch('canvas_render.wasm'))
.then(obj => {
const render = obj.instance.exports;
// Prepare pixel data
const width = canvas.width;
const height = canvas.height;
const pixelData = new Uint8ClampedArray(width * height * 4);
// Call WASM render function
render.render_scene(
pixelData.byteOffset,
width,
height
);
// Create ImageData and draw to Canvas
const imageData = new ImageData(pixelData, width, height);
ctx.putImageData(imageData, 0, 0);
});Combining WebGL with WASM:
// Using WASM to process WebGL vertex and texture data
const canvas = document.getElementById('glCanvas');
const gl = canvas.getContext('webgl');
// Load WASM module
WebAssembly.instantiateStreaming(fetch('webgl_render.wasm'))
.then(obj => {
const render = obj.instance.exports;
const memory = obj.instance.exports.memory;
// Create WebGL buffer
const positionBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
// Get vertex data from WASM memory
const vertexCount = render.get_vertex_count();
const vertexSize = 3 * 4; // 3 float32 (x,y,z)
const vertexData = new Float32Array(
memory.buffer,
render.get_vertex_data_offset(),
vertexCount * 3
);
// Upload data to WebGL
gl.bufferData(gl.ARRAY_BUFFER, vertexData, gl.STATIC_DRAW);
// Similar processing for texture data...
});Audio and Video Processing (FFmpeg Compiled to WASM)
Basic FFmpeg WASM Usage:
// Load FFmpeg WASM module
const { createFFmpeg, fetchFile } = FFmpeg;
const ffmpeg = createFFmpeg({ log: true });
async function processVideo(inputFile) {
await ffmpeg.load();
// Write input file to WASM virtual file system
ffmpeg.FS('writeFile', 'input.mp4', await fetchFile(inputFile));
// Execute FFmpeg command
await ffmpeg.run('-i', 'input.mp4', '-vf', 'scale=640:360', '-c:v', 'libx264', '-preset', 'fast', 'output.mp4');
// Read output file from WASM file system
const data = ffmpeg.FS('readFile', 'output.mp4');
// Create download link
const blob = new Blob([data.buffer], { type: 'video/mp4' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = 'processed.mp4';
a.click();
}Real-Time Audio/Video Processing:
// Using WASM for real-time audio processing
const audioContext = new AudioContext();
const processorNode = audioContext.createScriptProcessor(4096, 1, 1);
processorNode.onaudioprocess = (e) => {
const inputData = e.inputBuffer.getChannelData(0);
const outputData = e.outputBuffer.getChannelData(0);
// Write input data to WASM memory
const wasmMemory = wasmInstance.exports.memory;
const inputDataPtr = wasmInstance.exports.alloc(inputData.length * 4);
new Float32Array(wasmMemory.buffer, inputDataPtr, inputData.length).set(inputData);
// Call WASM processing function
wasmInstance.exports.process_audio(
inputDataPtr,
outputDataPtr,
inputData.length
);
// Read processed data from WASM memory
new Float32Array(wasmMemory.buffer, outputDataPtr, outputData.length).set(outputData);
// Free memory
wasmInstance.exports.free(inputDataPtr);
wasmInstance.exports.free(outputDataPtr);
};
// Connect audio nodes
sourceNode.connect(processorNode);
processorNode.connect(audioContext.destination);Game Development (Unity, Godot Engine Export to WASM)
Unity WebGL Export Configuration:
- In Unity Editor:
- File > Build Settings
- Select WebGL platform
- In Player Settings:
- Resolution and Presentation > Compression Format: Disable
- Publishing Settings > Enable Exceptions: Full
- Build output directory structure:
Build/ WebGl.data WebGl.loader.js WebGl.wasm WebGl.framework.js index.html
Godot Engine Export to WASM:
- Export Settings:
- Project > Export
- Select Web platform
- In Options:
- Export With: WebAssembly
- Threads: Enable (if multithreading is needed)
- Exported files:
export/ web/ godot.js godot.wasm godot.data index.html
Cryptographic Algorithms (RSA, AES Implementations in WASM)
RSA Encryption Example:
// RSA encryption implemented in WASM
WebAssembly.instantiateStreaming(fetch('crypto_wasm.wasm'))
.then(obj => {
const crypto = obj.instance.exports;
// Generate key pair
const keySize = 2048;
crypto.rsa_generate_keypair(keySize);
// Get public and private keys
const publicKeyPtr = crypto.rsa_get_public_key();
const privateKeyPtr = crypto.rsa_get_private_key();
// Encrypt data
const message = new TextEncoder().encode("Secret Message");
const encryptedPtr = crypto.rsa_encrypt(
publicKeyPtr,
message.byteOffset,
message.length
);
// Decrypt data
const decryptedPtr = crypto.rsa_decrypt(
privateKeyPtr,
encryptedPtr,
/* encrypted length */
);
// Read decrypted result
const decryptedLength = crypto.rsa_get_decrypted_length(decryptedPtr);
const decryptedData = new Uint8Array(
crypto.memory.buffer,
decryptedPtr,
decryptedLength
);
console.log(new TextDecoder().decode(decryptedData));
// Free memory
crypto.rsa_free_keypair();
crypto.rsa_free_buffer(publicKeyPtr);
crypto.rsa_free_buffer(privateKeyPtr);
crypto.rsa_free_buffer(encryptedPtr);
crypto.rsa_free_buffer(decryptedPtr);
});AES Encryption Example:
// AES encryption implemented in WASM
WebAssembly.instantiateStreaming(fetch('aes_wasm.wasm'))
.then(obj => {
const aes = obj.instance.exports;
// Set key
const key = new Uint8Array(32); // AES-256
crypto.getRandomValues(key);
const keyPtr = aes.aes_set_key(key.byteOffset, key.length);
// Encrypt data
const plaintext = new Uint8Array([/*...*/]);
const ciphertextPtr = aes.aes_encrypt(
keyPtr,
plaintext.byteOffset,
plaintext.length
);
// Decrypt data
const decryptedPtr = aes.aes_decrypt(
keyPtr,
ciphertextPtr,
/* ciphertext length */
);
// Read decrypted result
const decryptedLength = aes.aes_get_decrypted_length(decryptedPtr);
const decryptedData = new Uint8Array(
aes.memory.buffer,
decryptedPtr,
decryptedLength
);
console.log(decryptedData);
// Free memory
aes.aes_free_key(keyPtr);
aes.aes_free_buffer(ciphertextPtr);
aes.aes_free_buffer(decryptedPtr);
});Scientific Computing (Numerical Simulations, Matrix Operations)
Matrix Multiplication Example:
// High-performance matrix multiplication using WASM
WebAssembly.instantiateStreaming(fetch('matrix_wasm'))
.then(obj => {
const matrix = obj.instance.exports;
const memory = obj.instance.exports.memory;
// Matrix dimensions
const rowsA = 1024;
const colsA = 1024;
const colsB = 1024;
// Allocate matrix space in WASM memory
const matrixAPtr = matrix.matrix_multiplyllocate(
rowsA * colsA);
const matrixBPtr = matrix.matrix_multiply(colsA * rowsB);
const resultMatrixPtr = matrix.matrix_multiply(rowsA * colsB);
// Fill matrix data (example)
const matrixA = new Float32Array(memory.bufferData, matrixAPtr, rowsA * colsA);
const matrixB = new Float32Array(memory.bufferData, matrixBPtr, colsA * colsB);
// Initialize matrices (in real applications, data would come from other sources)
for (let i = 0; i < rowsA; i++) {
for (let j = 0; j < colsA; j++) {
matrixA[i * colsA + j] = Math.random();
}
}
for (let i = 0; i < colsA; i++) {
for (let j = 0; j < colsB; j++) {
matrixB[i * colsB + j] = Math.random();
}
}
// Perform matrix multiplication
matrix.matrix_multiply(
matrixAPtr,
matrixBPtr,
resultMatrixPtr,
rowsA,
colsA,
colsB
);
// Read result matrix
const resultMatrix = new Float32Array(memory.bufferData, resultMatrixPtr, rowsA * colsB);
// Process result...
// Free memory
matrix.matrix_free(matrixAPtr);
matrix.matrix_free(matrixBPtr);
matrix.matrix_free(resultMatrixPtr);
});Numerical Integration Example:
// Numerical integration calculation using WASM
WebAssembly.instantiateStreaming(fetch('numerical_wasm.wasm'))
.then(obj => {
const numerical = obj.instance.exports;
// Define integrand function (via callback)
function integrand(x) {
return Math.sin(x) / x; // Example function
}
// Set integration parameters
const a = 0.0001; // Lower bound (avoid x=0)
const b = 10.0; // Upper bound
const tolerance = 1e-6; // Tolerance
// Call WASM integration function
const resultPtr = numerical.numerical_integrate(
/* Callback function pointer - requires special handling */
a,
b,
tolerance
);
// Read result
const result = numerical.get_double_result(resultPtr);
console.log(`Integration result: ${result}`);
// Free memory
numerical.free_result(resultPtr);
});WebAssembly in Non-Web Environments
Node.js WASM Applications
High-Performance Computing:
// Using WASM to accelerate compute-intensive tasks in Node.js
const fs = require('fs');
const wasmBuffer = fs.readFileSync('compute_wasm.wasm');
WebAssembly.instantiate(wasmBuffer).then(obj => {
const compute = obj.instance.exports;
// Prepare large dataset
const dataSize = 1000000;
const inputData = new Float64Array(dataSize);
for (let i = 0; i < dataSize; i++) {
inputData[i] = Math.random();
}
// Allocate space in WASM memory
const inputPtr = compute.alloc(dataSize * 8); // 8 bytes per double
const outputPtr = compute.alloc(dataSize * 8);
// Copy data to WASM memory
new Float64Array(compute.memory.buffer, inputPtr, dataSize).set(inputData);
// Perform computation
compute.process_data(inputPtr, outputPtr, dataSize);
// Read result
const outputData = new Float64Array(compute.memory.buffer, outputPtr, dataSize);
console.log('Computation result:', outputData.slice(0, 10)); // Print first 10 results
// Free memory
compute.free(inputPtr);
compute.free(outputPtr);
});Plugin System:
// Implementing a Node.js plugin system using WASM
const { Worker } = require('worker_threads');
const path = require('path');
class WasmPlugin {
constructor(pluginPath) {
this.pluginPath = pluginPath;
this.instance = null;
}
async load() {
// Load WASM in Worker thread to avoid blocking main thread
return new Promise((resolve, reject) => {
const worker = new Worker(`
const { parentPort } = require('worker_threads');
const fs = require('fs');
const wasmPath = '${this.pluginPath}';
(async () => {
try {
const wasmBuffer = fs.readFileSync(wasmPath);
const obj = await WebAssembly.instantiate(wasmBuffer);
parentPort.postMessage({ success: true, instance: obj.instance });
} catch (err) {
parentPort.postMessage({ success: false, error: err.message });
}
})();
`, { eval: true });
worker.on('message', (msg) => {
if (msg.success) {
this.instance = msg.instance;
resolve();
} else {
reject(new Error(msg.error));
}
});
worker.on('error', reject);
worker.on('exit', (code) => {
if (code !== 0) {
reject(new Error(`Worker stopped with exit code ${code}`));
}
});
});
}
execute(methodName, ...args) {
if (!this.instance) {
throw new Error('Plugin not loaded');
}
// Find exported method
if (!this.instance.exports[methodName]) {
throw new Error(`Method ${methodName} not found in plugin`);
}
// Call method
return this.instance.exports[methodName](...args);
}
}
// Usage example
(async () => {
const plugin = new WasmPlugin(path.join(__dirname, 'plugin.wasm'));
await plugin.load();
const result = plugin.execute('process_data', inputData);
console.log('Plugin processing result:', result);
})();Server-Side WASM
WASM in Cloudflare Workers:
// Using WASM to process requests in Cloudflare Workers
export default {
async fetch(request) {
// Load WASM module
const wasmBuffer = await fetch('https://example.com/filter.wasm').then(res => res.arrayBuffer());
const wasmModule = await WebAssembly.compile(wasmBuffer);
const wasmInstance = await WebAssembly.instantiate(wasmModule);
// Read request body
const { headers, body } = request;
const contentType = headers.get('content-type') || '';
if (contentType.includes('application/json')) {
const text = await body.text();
const data = JSON.parse(text);
// Process data in WASM memory
const inputPtr = wasmInstance.exports.alloc(JSON.stringify(data).length);
const memory = new Uint8Array(wasmInstance.exports.memory.buffer);
for (let i = 0; i < text.length; i++) {
memory[inputPtr + i] = text.charCodeAt(i);
}
// Call WASM processing function
const outputPtr = wasmInstance.exports.process_data(inputPtr, text.length);
const outputLength = wasmInstance.exports.get_output_length(outputPtr);
const result = new TextDecoder().decode(
memory.slice(outputPtr, outputPtr + outputLength)
);
// Free memory
wasmInstance.exports.free(inputPtr);
wasmInstance.exports.free(outputPtr);
// Return processed result
return new Response(result, {
headers: { 'content-type': 'application/json' }
});
}
return new Response('Unsupported content type', { status: 400 });
}
};WASM in Fastly Compute@Edge:
// Using Rust and WASM to process requests in Fastly Compute@Edge
// Note: Actual code requires Rust; this shows the concept
// Pseudo-code example:
#[fastly::main]
async fn main(req: Request) -> Result<Response> {
// Load WASM module
let wasm_module = WASM::from_file("filter.wasm")?;
// Get request body
let body = req.get_body()?.as_bytes()?;
// Process data in WASM memory
let input_ptr = wasm_module.alloc(body.len())?;
wasm_module.write_memory(input_ptr, body)?;
// Call WASM processing function
let output_ptr = wasm_module.call("process_data", input_ptr, body.len())?;
let output_len = wasm_module.get_output_length(output_ptr)?;
let result = wasm_module.read_memory(output_ptr, output_len)?;
// Free memory
wasm_module.free(input_ptr)?;
wasm_module.free(output_ptr)?;
// Return processed result
Ok(Response::from_body(result))
}WASM in Embedded Devices
WASM in IoT Devices:
// Example of running WASM on embedded devices (conceptual code)
#include "wasm3.h"
void run_wasm_on_device() {
// Initialize WASM runtime
M3Environment *env = m3_NewEnvironment();
M3Runtime *runtime = m3_NewRuntime(env, 1024, NULL);
// Load WASM module (from flash or network)
uint8_t wasm_buffer[] = { /* WASM binary data */ };
M3Module *module = m3_ParseModule(env, wasm_buffer, sizeof(wasm_buffer));
M3Result result = m3_LoadModule(runtime, module);
if (result) {
printf("Failed to load module: %s\n", result);
return;
}
// Get exported function
IM3Function func = m3_FindFunction(runtime, "sensor_processing");
if (!func) {
printf("Function not found\n");
return;
}
// Prepare input data (read from sensors)
float sensor_data[10];
read_sensors(sensor_data, 10);
// Call WASM function
M3Value args[1] = { m3_MakeFloat(0) }; // Simplified example
M3Value rets[1];
result = m3_CallV(func, 1, args, 1, rets);
if (result) {
printf("Function call failed: %s\n", result);
return;
}
// Process result
float processed_data = m3_GetFloat(rets[0]);
send_processed_data(processed_data);
// Cleanup
m3_FreeRuntime(runtime);
m3_FreeEnvironment(env);
}WASM on Microcontrollers:
// Running WASM on microcontrollers using Rust (conceptual code)
#![no_std]
#![no_main]
use panic_halt as _;
use wasm3_rt as wasm3;
#[rtic::app(device = stm32f4xx_hal::stm32, peripherals = true)]
mod app {
use super::*;
#[shared]
struct Shared {}
#[local]
struct Local {
wasm_runtime: wasm3::Runtime,
wasm_module: wasm3::Module,
}
#[init]
fn init(cx: init::Context) -> (Shared, Local, init::Monotonics) {
// Initialize WASM runtime
let env = wasm3::Environment::new();
let runtime = env.new_runtime(1024).unwrap();
// Load WASM module (from Flash)
let wasm_bytes = include_bytes!("app.wasm");
let module = env.parse_module(wasm_bytes).unwrap();
let module = runtime.load_module(module).unwrap();
(Shared {}, Local { wasm_runtime: runtime, wasm_module: module }, init::Monotonics())
}
#[task(binds = TIM2, shared = [], local = [wasm_runtime, wasm_module])]
fn timer_tick(cx: timer_tick::Context) {
let locals = cx.local;
// Prepare input data (read from sensors)
let sensor_data = read_sensor_data();
// Call WASM function
let func = locals.wasm_module.find_function("process_sensor_data").unwrap();
let args = [wasm3::Value::I32(sensor_data as i32)];
let rets = [wasm3::Value::I32(0)];
func.call(&locals.wasm_runtime, &args, &rets).unwrap();
// Process result
let result = rets[0].as_i32();
control_actuator(result);
}
}WASM in Mobile Applications
WASM in React Native:
// Using WASM in React Native
import { useEffect, useState } from 'react';
import { View, Text } from 'react-native';
export default function App() {
const [result, setResult] = useState(null);
useEffect(() => {
async function loadAndRunWasm() {
try {
// Load WASM module
const wasm = await WebAssembly.instantiateStreaming(
fetch('mobile_wasm.wasm'),
{ env: { /* Possible imports */ } }
);
// Call WASM function
const processedData = wasm.instance.exports.process_data(
/* Input parameters */
);
setResult(processedData);
} catch (err) {
console.error('WASM loading failed:', err);
}
}
loadAndRunWasm();
}, []);
return (
<View>
<Text>WASM processing result: {result !== null ? result : 'Loading...'}</Text>
</View>
);
}WASM in Flutter Plugins:
// Dart-side Flutter plugin code
import 'dart:typed_data';
import 'package:flutter/services.dart';
import 'package:webview_flutter/webview_flutter.dart';
class WasmPlugin {
static const MethodChannel _channel = MethodChannel('wasm_plugin');
static Future<dynamic> runWasm(String wasmPath, Map<String, dynamic> input) async {
// Load and run WASM in platform-specific code
final result = await _channel.invokeMethod('run_wasm', {
'wasm_path': wasmPath,
'input': input,
});
return result;
}
}
// Platform-specific implementation (Android example)
// AndroidManifest.xml requires network permissions
// Implement platform channel in Kotlin
/*
class WasmPlugin(private val messenger: BinaryMessenger) : MethodCallHandler {
private val channel = MethodChannel(messenger, "wasm_plugin")
init {
channel.setMethodCallHandler(this)
}
override fun onMethodCall(call: MethodCall, result: Result) {
when (call.method) {
"run_wasm" -> {
val wasmPath = call.argument<String>("wasm_path")!!
val input = call.argument<Map<String, Any>>("input")!!
// Run WASM on Android
val wasmResult = runWasmOnAndroid(wasmPath, input)
result.success(wasmResult)
}
else -> result.notImplemented()
}
}
private fun runWasmOnAndroid(wasmPath: String, input: Map<String, Any>): Any {
// Use Android's WASM runtime (e.g., Wasmer Android)
// Implementation details...
}
}
*/WASM in Desktop Applications
WASM in Electron:
// Using WASM in Electron main process
const { app, BrowserWindow } = require('electron');
const path = require('path');
const fs = require('fs');
let mainWindow;
app.whenReady().then(() => {
mainWindow = new BrowserWindow({
webPreferences: {
nodeIntegration: true,
contextIsolation: false
}
});
mainWindow.loadFile('index.html');
// Optionally use WASM in main process
loadWasmInMainProcess();
});
async function loadWasmInMainProcess() {
try {
const wasmBuffer = fs.readFileSync(path.join(__dirname, 'desktop_wasm.wasm'));
const wasmModule = await WebAssembly.compile(wasmBuffer);
const wasmInstance = await WebAssembly.instantiate(wasmModule);
// Call WASM function
const result = wasmInstance.exports.process_data(
/* Input parameters */
);
console.log('WASM processing result:', result);
} catch (err) {
console.error('WASM loading failed:', err);
}
}WASM in Tauri:
// Using WASM in Tauri (Rust) backend
use tauri::command;
use wasmer::{imports, Instance, Module, Store, Value};
#[command]
fn process_data_with_wasm(input: Vec<f64>) -> Vec<f64> {
// Create WASM runtime
let store = Store::default();
// Load WASM module (from file or embedded)
let module = Module::from_file(&store, "data_processor.wasm")
.expect("Failed to load WASM module");
// Create import object (if needed)
let import_object = imports! {};
// Instantiate module
let instance = Instance::new(&module, &import_object)
.expect("Failed to instantiate WASM module");
// Get exported function
let process_func = instance.exports.get_function("process_data")
.expect("Failed to find process_data function");
// Prepare input memory
let input_ptr = process_func.call(&[Value::I32(input.len() as i32)])
.expect("Function call failed")
.get(0)
.unwrap()
.unwrap_i32() as *mut f64;
// Write input data
unsafe {
std::ptr::copy_nonoverlapping(input.as_ptr(), input_ptr, input.len());
}
// Call processing function
let output_ptr = process_func.call(&[Value::I32(input_ptr as i32)])
.expect("Function call failed")
.get(0)
.unwrap()
.unwrap_i32() as *mut f64;
// Read output data (assuming known output length)
let output_len = input.len(); // Simplified example
let mut output = vec![0.0; output_len];
unsafe {
std::ptr::copy_nonoverlapping(output_ptr, output.as_mut_ptr(), output_len);
}
output
}
fn main() {
tauri::Builder::default()
.invoke_handler(tauri::generate_handler![process_data_with_wasm])
.run(tauri::generate_context!())
.expect("error while running tauri application");
}WebAssembly Toolchain and Ecosystem
Emscripten Toolchain
Compiling C/C++ to WASM:
# Basic compilation command
emcc hello.c -o hello.html
# Advanced options example
emcc \
-O3 \ # Optimization level
-s WASM=1 \ # Enable WASM output
-s SIDE_MODULE=0 \ # Generate full module (not just library)
-s EXPORTED_FUNCTIONS='["_main", "_add"]' \ # Export functions
-s EXTRA_EXPORTED_RUNTIME_METHODS='["ccall", "cwrap"]' \ # Export runtime methods
-s ALLOW_MEMORY_GROWTH=1 \ # Allow memory growth
-s ENVIRONMENT='web,worker' \ # Supported environments
input.c -o output.js # Output fileEmscripten API Usage:
#include <emscripten.h>
// Use EMSCRIPTEN_KEEPALIVE to prevent function optimization
EMSCRIPTEN_KEEPALIVE
int add(int a, int b) {
return a + b;
}
// File system operation example
EMSCRIPTEN_KEEPALIVE
void save_to_file(const char* filename, const char* data) {
EM_ASM_({
var filename = UTF8ToString($0);
var data = UTF8ToString($1);
FS.writeFile(filename, data);
}, filename, data);
}
// Main function (if generating executable)
int main() {
printf("Hello from C!\n");
return 0;
}Rust and WASM
wasm-pack Toolchain:
# Initialize WASM project
wasm-pack init my-wasm-project
# Build WASM package
wasm-pack build --target web
# Development mode build (with hot reload)
wasm-pack build --target web --dev
# Release build (optimized)
wasm-pack build --target web --releasewasm-bindgen Example:
// src/lib.rs
use wasm_bindgen::prelude::*;
// Export function to JavaScript
#[wasm_bindgen]
pub fn greet(name: &str) -> String {
format!("Hello, {}!", name)
}
// Import JavaScript function
#[wasm_bindgen]
extern "C" {
#[wasm_bindgen(js_namespace = console)]
fn log(s: &str);
}
// Use imported function
#[wasm_bindgen]
pub fn log_message(msg: &str) {
log(msg);
}
// Handle complex data types
#[wasm_bindgen]
pub struct Person {
name: String,
age: u32,
}
#[wasm_bindgen]
impl Person {
#[wasm_bindgen(constructor)]
pub fn new(name: &str, age: u32) -> Person {
Person {
name: name.to_string(),
age,
}
}
#[wasm_bindgen(getter)]
pub fn name(&self) -> String {
self.name.clone()
}
#[wasm_bindgen(setter)]
pub fn set_name(&mut self, name: &str) {
self.name = name.to_string();
}
#[wasm_bindgen(getter)]
pub fn age(&self) -> u32 {
self.age
}
#[wasm_bindgen(setter)]
pub fn set_age(&mut self, age: u32) {
self.age = age;
}
}Go and WASM
TinyGo Toolchain:
# Install TinyGo
brew install tinygo # macOS
# Or download binary for your platform from the official site
# Compile to WASM
tinygo build -o main.wasm -target wasm ./main.go
# Compile with smaller memory configuration
tinygo build -o main.wasm -target wasm -opt=2 -no-debug ./main.goGo WASM Example:
// main.go
package main
import (
"syscall/js"
)
// Export function to JavaScript
func add(this js.Value, args []js.Value) interface{} {
a := args[0].Int()
b := args[1].Int()
return a + b
}
// Export string processing function
func greet(this js.Value, args []js.Value) interface{} {
name := args[0].String()
return "Hello, " + name + "!"
}
func main() {
// Register exported functions
js.Global().Set("add", js.FuncOf(add))
js.Global().Set("greet", js.FuncOf(greet))
// Keep program running
select {}
}Go WASM with DOM Interaction:
// dom_example.go
package main
import (
"syscall/js"
)
func main() {
// Wait for DOM to load
document := js.Global().Get("document")
body := document.Call("getElementsByTagName", "body").Index(0)
// Create button
button := document.Call("createElement", "button")
button.Set("innerHTML", "Click me!")
// Set click event handler
clickHandler := js.FuncOf(func(this js.Value, args []js.Value) interface{} {
js.Global().Call("alert", "Button clicked from Go!")
return nil
})
button.Call("addEventListener", "click", clickHandler)
// Add button to page
body.Call("appendChild", button)
// Keep program running
select {}
}WebAssembly Component Model
Component Model Proposal Overview:
- Goal: Enable WASM modules to be composed like components
- Key Features:
- Clearly defined interfaces
- Type-safe imports/exports
- Interoperability between components written in multiple languages
Component Model Example (Conceptual):
;; Define a component interface
(component
(import "math" "add" (func $add (param i32 i32) (result i32)))
(import "env" "log" (func $log (param string)))
;; Export component functionality
(export "calculate" (func $calculate))
;; Component internal function
(func $calculate (param $a i32) (param $b i32) (result i32)
local.get $a
local.get $b
call $add
)
)
;; Implement component
(instance
(instantiate
(component
;; Component definition...
)
;; Provide import implementations
(import "math" "add" (func $add (param i32 i32) (result i32))
;; Implement add function
(func (param $a i32) (param $b i32) (result i32)
local.get $a
local.get $b
i32.add
)
)
(import "env" "log" (func $log (param string))
;; Implement log function
(func (param $msg string)
;; In practice, may call host logging functionality
)
)
)
)Current Tool Support:
- Partial component model support in Wasmtime and Wasmer
- Rust’s wasm-component crate
- Experimental toolchain support
WASM Ecosystem
WASI (WebAssembly System Interface):
# Run WASM module with WASI
wasmer run --enable-wasi my_wasi_app.wasm
# Example with file system access
wasmer run --dir=/tmp --env=MY_ENV_VAR=value my_wasi_app.wasmWASI Example Code (C):
#include <wasi/api.h>
#include <stdio.h>
int main() {
// Use WASI API to access file system
__wasi_fd_t fd;
__wasi_errno_t err = __wasi_fd_prestat_get(0, &fd); // Example call
// More practical file operation example
char buf[1024];
size_t bytes_read;
err = __wasi_fd_read(0, buf, sizeof(buf), &bytes_read);
if (err == 0) {
// Process read data
}
return 0;
}Wasmtime Runtime:
# Install Wasmtime
curl https://wasmtime.dev/install.sh -sSf | bash
# Run WASM module
wasmtime hello.wasm
# Run with configuration
wasmtime --enable-multi-memory --max-wasm-stack=1MB hello.wasm
# Run as HTTP service on server
wasmtime serve --port 8080 ./wasm_modules/Wasmer Runtime:
# Install Wasmer
curl https://get.wasmer.io -sSfL | sh
# Run WASM module
wasmer run hello.wasm
# Run with WASI
wasmer run --enable-wasi my_wasi_app.wasm
# Use Wasmer in Python
python3 -c "from wasmer import Instance; instance = Instance('hello.wasm'); print(instance.exports.hello())"



