Working with WebAssembly and JavaScript: From A to Z in Node.js

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Introduction to WebAssembly and its Role in Node.js

\n\n

WebAssembly (WASM) is a low-level binary instruction format that runs in a virtual machine with near-native performance. In the Node.js ecosystem, WebAssembly opens new horizons: it allows executing code written in C, C++, Rust, or Go directly in the server environment. This is especially relevant for tasks requiring high performance: image processing, cryptography, data parsing, working with large arrays of numbers.

\n\n

In this article, we will cover the complete workflow of working with WebAssembly in Node.js: from compiling source code to integrating the finished module into a JavaScript application.

\n\n

Basic Concepts and Environment Setup

\n\n

What You Need to Know Before Starting

\n

A WebAssembly module is a binary file with the .wasm extension. It does not have direct access to the DOM or file system — all interaction occurs through "imported functions" that you pass from JavaScript. In Node.js, this limitation is removed using special wrappers.

\n\n

Installing Tools

\n

To compile code to WASM, we need the Emscripten SDK. Installation on Linux/macOS:

\n
git clone https://github.com/emscripten-core/emsdk.git\ncd emsdk\n./emsdk install latest\n./emsdk activate latest\nsource ./emsdk_env.sh
\n\n

For Rust projects, use wasm-pack:

\n
npm install -g wasm-pack
\n\n

Creating and Compiling Your First WASM Module

\n\n

Example in C — Addition Function

\n

Let's create a simple function in C that adds two numbers:

\n
// math.c\n#include <emscripten.h>\n\nEMSCRIPTEN_KEEPALIVE\nint add(int a, int b) {\n    return a + b;\n}\n\nEMSCRIPTEN_KEEPALIVE\nint multiply(int a, int b) {\n    return a * b;\n}
\n\n

Compile to WASM using Emscripten:

\n
emcc math.c -o math.js -s EXPORTED_FUNCTIONS="['_add', '_multiply']" -s WASM=1 -s MODULARIZE=1 -s EXPORT_NAME="createMathModule"
\n\n

The output produces two files: math.wasm and math.js — a wrapper for loading.

\n\n

Loading the Module in Node.js

\n

Now use the module in JavaScript:

\n
// index.js\nconst createMathModule = require('./math.js');\n\ncreateMathModule().then(module => {\n    const add = module._add;\n    const multiply = module._multiply;\n\n    console.log('5 + 3 =', add(5, 3));        // 8\n    console.log('4 * 7 =', multiply(4, 7));  // 28\n});
\n\n

Run it:

\n
node index.js
\n\n

Working with Memory and Complex Data Types

\n\n

Passing Strings and Arrays

\n

WASM only operates with numbers. To pass strings or arrays, you need to allocate memory in the module's linear memory. Let's look at an example in C that accepts a string and returns its length:

\n
// string_ops.c\n#include <string.h>\n#include <emscripten.h>\n\nEMSCRIPTEN_KEEPALIVE\nint string_length(char* str) {\n    return strlen(str);\n}\n\nEMSCRIPTEN_KEEPALIVE\nvoid to_upper(char* str) {\n    for (int i = 0; str[i]; i++) {\n        if (str[i] >= 'a' && str[i] <= 'z') {\n            str[i] -= 32;\n        }\n    }\n}
\n\n

Compile it:

\n
emcc string_ops.c -o string_ops.js -s EXPORTED_FUNCTIONS="['_string_length', '_to_upper']" -s WASM=1 -s MODULARIZE=1 -s EXPORT_NAME="createStringModule"
\n\n

JavaScript code for working with memory:

\n
const createStringModule = require('./string_ops.js');\n\ncreateStringModule().then(module => {\n    const { _string_length, _to_upper, heap } = module;\n    \n    // Allocate memory for the string\n    const input = "hello world";\n    const ptr = module._malloc(input.length + 1);\n    \n    // Copy the string into WASM memory\n    for (let i = 0; i < input.length; i++) {\n        heap[i + ptr] = input.charCodeAt(i);\n    }\n    heap[ptr + input.len                

Blogs

Book Recommendations