emnapi: Node-API for WebAssembly

1.10.0 · active · verified Wed Apr 22

emnapi provides a robust implementation of Node-API (N-API) tailored for Emscripten, WASI-SDK, and clang with WebAssembly support. Its primary goal is to enable developers to port existing Node-API native addons to WebAssembly with minimal code modifications, striving to ensure runtime behavior closely matches native Node.js environments. The library is actively developed, with its current stable version being v1.10.0, released through a consistent cadence of frequent updates addressing bug fixes and new Node-API features. A key differentiator is its role in powering WebAssembly capabilities for projects like napi-rs and enabling Node.js native addons within environments like StackBlitz's WebContainer. It aims to synchronize Node-API changes from the upstream Node.js project, ensuring compatibility and feature parity.

Common errors

Warnings

Install

Imports

Quickstart

This quickstart demonstrates how to load a WebAssembly module (e.g., `hello.wasm`) compiled with emnapi, instantiate it in a Node.js environment using the `emnapi` runtime, and invoke an exported function from JavaScript/TypeScript.

import { readFileSync } from 'node:fs';
import { fileURLToPath } from 'node:url';
import { dirname, join } from 'node:path';
import { getNapiRuntime } from 'emnapi';

// In a CommonJS environment, replace 'import.meta.url' with '__filename' and 'dirname(fileURLToPath(...))' with '__dirname'.
const currentModuleDir = typeof __dirname !== 'undefined' ? __dirname : dirname(fileURLToPath(import.meta.url));

// Assuming 'hello.wasm' is compiled from C/C++ using emnapi and placed next to this script.
const wasmPath = join(currentModuleDir, './hello.wasm');
const wasmBytes = readFileSync(wasmPath);

async function runWasmModule() {
  try {
    // Initialize the emnapi runtime for the WebAssembly instance
    const napi = getNapiRuntime();

    // Instantiate the WebAssembly module with the emnapi imports
    // The 'napi' object is crucial for providing the N-API environment to the WASM module.
    const { instance } = await WebAssembly.instantiate(wasmBytes, { napi });

    // Access exported functions from the WASM module
    // For a simple 'hello world' N-API module compiled with emnapi, it might expose a function like 'hello'.
    // The exact function name depends on your C/C++ N-API addon's exports.
    const helloFunction = instance.exports.hello; // Replace 'hello' with your actual exported function name

    if (typeof helloFunction === 'function') {
      const result = helloFunction();
      console.log('Result from WASM module:', result); // Expected output might be 'world' or similar
    } else {
      console.error('The exported function "hello" was not found or is not a function in the WASM module.');
    }
  } catch (err) {
    console.error('Failed to load or run WASM module with emnapi:', err);
  }
}

runWasmModule();

view raw JSON →