DEV Community

loading...
Cover image for Getting Started with AssemblyScript & WASM

Getting Started with AssemblyScript & WASM

zoedreams profile image ☮️✝️☪️🕉☸️✡️☯️ ・4 min read

Overview

Beef up your development abilities with AssemblyScript and jump into high performant javascript & typescript modules without any previous knowledge of how to program assembly; with all of the benefits -- mostly ;) AssemblyScript targets WebAssembly's feature set specifically, giving developers low-level control over their code. Being a variant of TypeScript makes it easy to compile to WebAssembly without learning a new language. Integrates with the existing Web ecosystem - no heavy toolchains to set up. Simply npm install it!

Live Editor

Introduction

AssemblyScript compiles a strict variant of TypeScript (a typed superset of JavaScript) to WebAssembly using Binaryen, looking like:

export function fib(n: i32): i32 {
  var a = 0, b = 1
  if (n > 0) {
    while (--n) {
      let t = a + b
      a = b
      b = t
    }
    return b
  }
  return a
}
Enter fullscreen mode Exit fullscreen mode
asc fib.ts -b fib.wasm -O3
Enter fullscreen mode Exit fullscreen mode

Its architecture differs from a JavaScript VM in that it compiles a program ahead of time, quite similar to other static compilers. One can think of it as a mix of TypeScript's syntax and C's capabilities.

In a nutshell

On top of WebAssembly types, it not only provides low-level built-ins to access WebAssembly features directly, making it suitable as a thin layer on top of Wasm, but also comes with its own JavaScript-like standard library, making it suitable for non-browser use cases, along a relatively small managed runtime (with memory management and garbage collection) enabling the creation of programs that look and feel much like TypeScript.

For example, on the lowest level, memory can be accessed using the load<T>(offset) and store<T>(offset, value) built-ins that compile to WebAssembly instructions directly

store<i32>(8, load<i32>(0) + load<i32>(4))
Enter fullscreen mode Exit fullscreen mode

while the standard library not only provides optimized native Math implementations (both double and single precision) but also implementations of ArrayBuffer, Uint8Array, String, Map etc. on a higher level:

var view = new Int32Array(12)
view[2] = view[0] + view[1]
Enter fullscreen mode Exit fullscreen mode

In turn it also comes with a bunch of features JavaScript doesn't have, mostly out of necessity, like the ability to declare operator overloads that arrays for example use as an implementation helper. It's not quite a subset, not quite a superset, but rather a variant.

As of today, the compiler still has its limitations and we are patiently waiting for and prototyping future WebAssembly features (marked as 🦄 throughout the documentation) to see where these can help.

Sounds appealing to you? Read on!

Quick Start

Paving the way to what might be your first AssemblyScript module.

Prerequisites

The following assumes that a recent version of Node.js (version 12.x+) and its package manager npm (comes with Node.js) are installed, with the commands below executed in a command prompt. Basic knowledge about writing and working with TypeScript modules, which is very similar, is a plus.

Setting up a new project

To get started with AssemblyScript, switch to a new directory and initialize a new node module:

npm init
Enter fullscreen mode Exit fullscreen mode

Now install both the loader and the compiler using npm. Let's assume that the compiler is not required in production and make it a development dependency:

npm install --save @assemblyscript/loader
npm install --save-dev assemblyscript
Enter fullscreen mode Exit fullscreen mode

::: tip
If you need a specific version of the loader and/or the compiler, append the respective version number as usual.
:::

Once installed, the compiler provides a handy scaffolding utility to quickly set up a new AssemblyScript project, for example in the directory of the just initialized node module:

npx asinit .
Enter fullscreen mode Exit fullscreen mode

It automatically creates the recommended directory structure and configuration files:

This command will make sure that the following files exist in the project
directory '/path/to/mymodule':

  ./assembly
  Directory holding the AssemblyScript sources being compiled to WebAssembly.

  ./assembly/tsconfig.json
  TypeScript configuration inheriting recommended AssemblyScript settings.

  ./assembly/index.ts
  Example entry file being compiled to WebAssembly to get you started.

  ./build
  Build artifact directory where compiled WebAssembly files are stored.

  ./build/.gitignore
  Git configuration that excludes compiled binaries from source control.

  ./index.js
  Main file loading the WebAssembly module and exporting its exports.

  ./tests/index.js
  Example test to check that your module is indeed working.

  ./asconfig.json
  Configuration file defining both a 'debug' and a 'release' target.

  ./package.json
  Package info containing the necessary commands to compile to WebAssembly.

Do you want to proceed? [Y/n]
Enter fullscreen mode Exit fullscreen mode

Once initialized, edit the sources in assembly/, tweak compiler options in asconfig.json to fit your needs, and run the build command to compile your module to WebAssembly:

npm run asbuild
Enter fullscreen mode Exit fullscreen mode

Next steps

Once compiled, you may run the tests in tests/index.js:

npm test
Enter fullscreen mode Exit fullscreen mode

add imports to the generated index.js (instantiates the module and re-exports it):

...
const imports = {
  "assembly/index": {
    declarredImportedFunction: function(...) { ... }
  }
};
...
Enter fullscreen mode Exit fullscreen mode

and ultimately use your WebAssembly module like a normal node module:

const myModule = require("path/to/mymodule");
myModule.add(1, 2);
Enter fullscreen mode Exit fullscreen mode

::: tip NOTE
Your module's exports only understand integers and floats for now, with strings and objects being passed as pointers, but we'll get into that later when covering the loader.
:::

Enjoy :)

Even more reading material at our GitHub Repos

And don't forget to stop by our Discord server for live help and additional resources. Be sure to follow me for updates and tips on accelerating your webdev with AssemblyScript and WebAssembly. Thank you for reading, and happy coding.

Discussion (1)

pic
Editor guide
Collapse
wrldwzrd89 profile image
Eric Ahnell

Very interesting... WebAssembly continues getting new use cases as people experiment with it. Happy coding, indeed!