Hello World
Note: The final code for this example can be found on Github: hello-world.
In this introductory example, we will develop a NodeJS-based application that calls a WebAssembly module that in turn, calls a native "OS" function. This is exactly the same call chain as was used in the client-side example:
JavaScript --> WebAssembly --> Native "OS" function
In this case, we will invoke the a simple WASI module that does nothing more than writing hello world to standard out.
However, as we saw with the client-side hello-world example, file descriptors such as "standard in" and "standard out" are not normally available to a WebAssembly module since they belong to the underlying "OS". Therefore, we must again make use of the following package:
Package Name
Description
@wasmer/wasi
A set of JavaScript polyfills that bridge the gap between the black-box world of a WebAssembly module and functionality available from the host environment
Important
Notice that for a server-side implementation, the @wasmer/wasmfs package is not needed.

Setup Instructions

Step-By-Step Guide

  1. 1.
    Change into some development directory
    1
    $ cd <some_development_directory>
    Copied!
  2. 2.
    Create and then change into a new project directory, then run npm init
    1
    $ mkdir wasmer-js-node-hello-world
    2
    $ cd wasmer-js-node-hello-world
    3
    $ npm init
    Copied!
    After answering all the questions from npm init, you will have a configured package.json file.
  3. 3.
    Declare the use of package @wasmer/wasi as a runtime dependency by running the command:
    1
    $ npm install --save @wasmer/wasi
    Copied!
  4. 4.
    Download the WebAssembly module helloworld.wasm and store it in this directory
  5. 5.
    Create the file index.js and add the coding shown below.
    Important Difference
    In contrast to running in the browser, the server-side implementation of the same Wasm module is noticeably smaller.
    When running server-side, we do not need to write any code to obtain the contents of standard out after the Wasm module has executed, since when running server-side, anything written to standard out by a Wasm module appears directly in the console.
    1
    const fs = require("fs")
    2
    const { WASI } = require("@wasmer/wasi")
    3
    const nodeBindings = require("@wasmer/wasi/lib/bindings/node")
    4
    ​
    5
    const wasmFilePath = "./helloworld.wasm"
    6
    ​
    7
    // Instantiate a new WASI Instance
    8
    let wasi = new WASI({
    9
    args: [wasmFilePath],
    10
    env: {},
    11
    bindings: {
    12
    ...(nodeBindings.default || nodeBindings),
    13
    fs: fs
    14
    }
    15
    })
    16
    ​
    17
    // Async function to run our Wasm module/instance
    18
    const startWasiTask =
    19
    async pathToWasmFile => {
    20
    // Fetch our Wasm File
    21
    let wasmBytes = new Uint8Array(fs.readFileSync(pathToWasmFile)).buffer
    22
    ​
    23
    // Instantiate the WebAssembly file
    24
    let wasmModule = await WebAssembly.compile(wasmBytes);
    25
    let instance = await WebAssembly.instantiate(wasmModule, {
    26
    ...wasi.getImports(wasmModule)
    27
    });
    28
    ​
    29
    // Start the WASI instance
    30
    wasi.start(instance)
    31
    }
    32
    ​
    33
    // Everything starts here
    34
    startWasiTask(wasmFilePath)
    Copied!
  6. 6.
    Save index.js and run it using:
    1
    $ node index.js
    2
    Hello World!
    Copied!
Next, let's take a look at running Wasm modules whose interfaces require transformation.
If you want to run the examples from the docs codebase directly, you can also do:
1
git clone https://github.com/wasmerio/docs.wasmer.io.git
2
cd docs.wasmer.io/integrations/js/wasi/server/examples/hello-world
3
npm run dev
Copied!
Last modified 25d ago