Get started with WebAssembly using TypeScript: Part 1

Get started with WebAssembly using TypeScript: Part 1

WebAssembly has the potential to be a major shift in how we build software for the web, the cloud, IOT, and more. Its portable and secure nature opens up use-cases that were previously very difficult to achieve. Let's walk through what it takes to get started so you can start experimenting with everything Wasm can do. In this first Foundations post, we'll get the tools you'll need set up, and we'll build some TypeScript code into a WebAssembly module. In future posts, we'll look at various things you may want to do with Wasm such as running it in the cloud with Atmo, run it in the browser, and more.

Before we start, remember that WebAssembly is not a language unto itself, it is a format that various languages can be compiled into, and that format can be used to run your code on various platforms and devices. Wasm is commonly thought of as a browser-based technology, but it actually has countless applications. Suborbital focuses on the cloud native uses for WebAssembly, but that's just one aspect! The WebAssembly format is very safe as it runs your code within a sandbox, and it is very efficiently as the only thing contained in the module is your code, nothing more. Alright, let's get into it.

The tooling

There are several ways you can go about building code into WebAssembly, and they largely vary by language. If you're a Rust developer, the cargo toolchain includes support for WebAssembly targets. If you're a TypeScript developer, the AssemblyScript project includes the asc tool which compiles code into Wasm. In order to simplify development of WebAssembly across several languages, we use the subo CLI to distill these language differences down into a single command: subo build.

Let's install subo:

curl -Ls https://subo.suborbital.dev | sh

Note this method does not work on M1 Macs currently. You can clone the subo repo and run make subo to install it manually.

Ensure the installation succeeded by running subo --version

Create a project

Now that you've got the tool installed, you can create your first WebAssembly project:

subo create runnable myfirstmodule --lang typescript

This will create a new directory that includes a TypeScript codebase ready to be built with subo and the AssemblyScript toolchain. All of the action resides in the src/lib.ts file, so let's take a look at that:

import { logInfo } from "@suborbital/suborbital"

export function run(input: ArrayBuffer): ArrayBuffer {
    let inStr = String.UTF8.decode(input)

    let out = "hello, " + inStr

    logInfo(out)

    return String.UTF8.encode(out)
}

We can see that we have a function here that takes in bytes as input and returns bytes as output. Since this code is intended to be built with AssemblyScript, you can see it uses its standard library with functions like String.UTF8.decode. AssemblyScript's standard library is designed to be very strictly typed and remain very performant when compiled to WebAssembly.

Build into WebAssembly

Before we build the code, you should know that subo can build your code in two different ways. It can either use the npm toolchain you have installed on your machine, or it can use Docker to build the code if you dont have npm installed already. This guide will assume you have npm installed, and therefore we'll be passing the --native flag below. If you don't have npm installed but you do have Docker, just omit it.

Now that we have some code to compile, let's try it out:

cd myfirstmodule
subo build . --native

You should see something like this:

ℹ️  building single Runnable (run from project root to create bundle)
ℹ️  🔗 using native toolchain
⏩ START: building runnable: myfirstmodule (assemblyscript)
⏩ START: missing node_modules, fixing...

added 5 packages, and audited 6 packages in 2s

found 0 vulnerabilities
✅ DONE: fixed!

> asbuild
> asc src/index.ts --target release --use abort=src/index/abort

✅ DONE: myfirstmodule was built -> /Users/cohix-so/Workspaces/suborbital/myfirstmodule/myfirstmodule.wasm

Awesome! You should now see a .wasm file in the directory! We've successfully built our first WebAssembly code.

What's next

The next post in this series will look at running this module embedded in a Go application, and then we'll explore using WebAssembly in the browser. If you'd like to get a jump start, you can check out running WebAssembly in Go, which will be covered in detail in the next post!

Cover photo by 贝莉儿 DANIST on Unsplash

Sign up for the Suborbital Launch Pad newsletter to get information like this and other updates about the WebAssembly and cloud native ecosystems in your inbox!