bugl
bugl
HomeLearnPatternsSearch
HomeLearnPatternsSearch

Loading lesson path

Learn/Node.js/Node.js Advanced
Node.js•Node.js Advanced

Node.js WebAssembly

Concept visual

Node.js WebAssembly

Graph traversalgraph
ABCDE
current
queued
1
4

Start from A

What is WebAssembly?

WebAssembly (Wasm)

Formula

is a binary instruction format designed as a portable compilation target for high - level languages like C, C ++, and Rust.

Key characteristics of WebAssembly include:

Binary format

  • Compact size that loads and executes faster than JavaScript

Near-native performance

  • Executes at speeds close to native machine code

Platform independent

  • Runs on browsers, Node.js, and other environments

Safety

  • Executes in a sandboxed environment with a strong security model

Formula

Unlike JavaScript, WebAssembly is a low - level binary format that isn't meant to be written by hand.

Instead, you compile code from other languages into WebAssembly. WebAssembly Support in Node.js

Node.js provides built-in support for WebAssembly through the global
WebAssembly object (just like in browsers).

To check if your Node.js version supports WebAssembly:

Example: Check WebAssembly Support console.log(typeof WebAssembly === 'object');

console.log(WebAssembly);

Note:

WebAssembly support was first added in Node.js v8.0.0 and has improved in subsequent versions. Using WebAssembly in Node.js The WebAssembly API in Node.js provides several methods for working with WebAssembly modules:

Method

Description

WebAssembly.compile() Compiles WebAssembly binary code into a WebAssembly module WebAssembly.instantiate()

Compiles and instantiates WebAssembly code

WebAssembly.validate()

Validates a WebAssembly binary format

WebAssembly.Module

Represents a compiled WebAssembly module

WebAssembly.Instance

Represents an instantiated WebAssembly module

WebAssembly.Memory

Represents WebAssembly memory

Here's a basic example of loading and running a WebAssembly module:

Example: Running WebAssembly in Node.js const fs = require('fs');

// Read the WebAssembly binary file const wasmBuffer = fs.readFileSync('./simple.wasm');

// Compile and instantiate the module

WebAssembly.instantiate(wasmBuffer).then(result => {
const instance = result.instance;
// Call the exported 'add' function const sum = instance.exports.add(2, 3);
console.log('2 + 3 =', sum); // Output: 2 + 3 = 5
});

Note:

The simple.wasm file in this example would be a compiled WebAssembly module that exports an add function. You would typically create this by compiling C, C++, or Rust code.

Working with Different Languages

You can compile various languages to WebAssembly for use in Node.js:

C/C++ with Emscripten

Formula

Emscripten is a compiler toolchain for C/C ++ that outputs WebAssembly.

Example C Code (add.c):

Formula

#include < emscripten.h >

EMSCRIPTEN_KEEPALIVE

int add(int a, int b) {
return a + b;
}

Compile to WebAssembly:

Formula

emcc add.c - s WASM = 1 - s EXPORTED_FUNCTIONS ='["_add"]' - o add.js
Rust with wasm - pack wasm - pack is a tool for building Rust - generated WebAssembly.

Example Rust Code (src/lib.rs):

use wasm_bindgen::prelude::*;
#[wasm_bindgen]
pub fn add(a: i32, b: i32) -> i32 {

Formula

a + b
}

Build with wasm-pack:

Formula

wasm - pack build -- target nodejs

Advanced WebAssembly Usage

  1. Working with Complex Data Structures Passing complex data between JavaScript and WebAssembly requires careful memory management:

Example: Passing Arrays to WebAssembly

// JavaScript code const wasmModule = await WebAssembly.instantiate(wasmBuffer, {
env: {
memory: new WebAssembly.Memory({ initial: 1 })
}
});
// Allocate memory for an array of 10 integers (4 bytes each)
const arraySize = 10;
const ptr = wasmModule.exports.alloc(arraySize * 4);
const intArray = new Int32Array(wasmModule.exports.memory.buffer, ptr, arraySize);
// Fill array with values for (let i = 0; i < arraySize; i++) {
intArray[i] = i * 2;
}
// Call WebAssembly function to process the array const sum = wasmModule.exports.processArray(ptr, arraySize);
console.log('Sum of array:', sum);
// Don't forget to free the memory wasmModule.exports.dealloc(ptr, arraySize * 4);
Corresponding C Code (compiled to WebAssembly):

Formula

#include < stdlib.h >
int* alloc(int size) {
return (int*)malloc(size);
}
void dealloc(int* ptr, int size) {
free(ptr);
}
int processArray(int* array, int length) {
int sum = 0;
for (int i = 0; i < length; i++) {
sum += array[i];
}
return sum;
}
  1. Multithreading with WebAssembly WebAssembly supports multithreading through Web Workers and SharedArrayBuffer:

Example: Parallel Processing with WebAssembly

// main.js const workerCode = `
const wasmModule = await WebAssembly.instantiate(wasmBuffer, {
env: { memory: new WebAssembly.Memory({ initial: 1, shared: true }) }
});
self.onmessage = (e) => {
const { data, start, end } = e.data;
const result = wasmModule.exports.processChunk(data, start, end);
self.postMessage({ result });
};
`;
// Create worker pool const workerCount = navigator.hardwareConcurrency || 4;
const workers = Array(workerCount).fill().map(() => {
const blob = new Blob([workerCode], { type: 'application/javascript' });
return new Worker(URL.createObjectURL(blob));
});
// Process data in parallel async function processInParallel(data, chunkSize) {
const results = [];
let completed = 0;
return new Promise((resolve) => {
workers.forEach((worker, i) => {
const start = i * chunkSize;
const end = Math.min(start + chunkSize, data.length);
worker.onmessage = (e) => {
results[i] = e.data.result;
completed++;
if (completed === workerCount) {
resolve(results);
}
};
worker.postMessage({ data, start, end });
});
});
}
  1. Debugging WebAssembly Debugging WebAssembly can be challenging, but modern tools can help:

Using Source Maps with Emscripten

# Compile with debugging information and source maps emcc -g4 --source-map-base http://localhost:8080/ -s WASM=1 -s EXPORTED_FUNCTIONS='["_main","_my_function"]' -o output.html source.c

Debugging in Chrome DevTools

Open Chrome DevTools (F12) Go to the "Sources" tab Find your WebAssembly file in the file tree Set breakpoints and inspect variables as with JavaScript

Previous

Node.js Microservices

Next

Node.js HTTP/2 Module