Hello World

circle-check

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 examplearrow-up-right, 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

circle-exclamation

Important

Setup Instructions

Step-By-Step Guide

  1. Change into some development directory

     $ cd <some_development_directory>
  2. Create and then change into a new project directory, then run npm init

     $ mkdir wasmer-js-node-hello-world
     $ cd wasmer-js-node-hello-world
     $ npm init

    After answering all the questions from npm init, you will have a configured package.json file.

  3. Declare the use of package @wasmer/wasi as a runtime dependency by running the command:

    $ npm install --save @wasmer/wasi
  4. Download the WebAssembly module helloworld.wasmarrow-up-right and store it in this directory

  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.

     const fs       = require("fs")
     const { WASI } = require("@wasmer/wasi")
     const nodeBindings = require("@wasmer/wasi/lib/bindings/node")
    
     const wasmFilePath = "./helloworld.wasm"
    
     // Instantiate a new WASI Instance
     let wasi = new WASI({
       args: [wasmFilePath],
       env: {},
       bindings: {
         ...(nodeBindings.default || nodeBindings),
         fs: fs
       }
     })
    
     // Async function to run our Wasm module/instance
     const startWasiTask =
       async pathToWasmFile => {
         // Fetch our Wasm File
         let wasmBytes = new Uint8Array(fs.readFileSync(pathToWasmFile)).buffer
    
         // Instantiate the WebAssembly file
         let wasmModule = await WebAssembly.compile(wasmBytes);
         let instance = await WebAssembly.instantiate(wasmModule, {
           ...wasi.getImports(wasmModule)
         });
    
         // Start the WASI instance
         wasi.start(instance)
       }
    
     // Everything starts here
     startWasiTask(wasmFilePath)
  6. Save index.js and run it using:

     $ node index.js
     Hello World!

Next, let's take a look at running Wasm modules whose interfaces require transformation.

circle-info

If you want to run the examples from the docs codebase directly, you can also do:

Last updated