DEV Community

Michael Levan
Michael Levan

Posted on • Edited on

Building And Running Apps In WASM

Software development has gone through several stages over the past 20-30 years. It went from writing your own garbage collection for memory consumption to asking an AI chatbot to write a try/except block for you. A big method of change has been around how apps are run, tested, and compiled not only locally, but across systems/platforms from VMs to Serverless to Kubernetes.

In this blog post, you’ll learn about one of the newest/hottest methods - WASM.

WASM Recap

WASM brings performance enhancements (20-160% faster than standard containers), cross-architecture capabilities (build on an ARM-based device and run it on x64), security (watered-down Scratch-like Operating Systems), and cross-language support (you write in Python, I write in Go, and it’s all the same at compile time).

To break down some key verbiage:

  • WASM == Run browser-based apps
  • WASI == Interface to interact with resources locally and/or server-side (like files and networks). It's an extension of WASM.
  • Runtimes == How to run the wasm-compiled app locally or on a server (Wasmtime which is the most popular right now, Wazmer, Wazero, etc.)

Installation

When installing WASM locally or server-side, there are going to be a few pieces:

  • WASI
  • The runtime

When installing runtimes (like Wasmtime), WASI automatically exists.

For the purposes of this blog post, you’ll see how to install Wasmtime. The reason is that at the time of writing this, it was the most popular.

💡

There are a lot of runtimes coming out around WASM because it’s still so new and everyone is trying to “figure it out”. This is a common theme with either new technologies or technologies that have been around for a while and are finally getting “fame”.

To install WASM, run a curl command that brings down a Bash script that runs the installation.

curl https://wasmtime.dev/install.sh -sSf | bash

Enter fullscreen mode Exit fullscreen mode

You should see an output similar to the one below.

Image description

Make sure that you restart your terminal before trying to use WASM.

To confirm that the binary was installed successfully, you can test out the help command.

Image description

💡

If you’re on Windows, check out the precompiled packages: https://github.com/bytecodealliance/wasmtime/releases

Running Code Locally With WASM

Now that WASM and WASI are installed successfully, it’s time to test out some code and see how it works with WASM. For the purposes of this blog post, you’ll use a “Hello World” style Go application. Even if you don’t know Go, that’s totally fine. This is just to give you an example.

If you don’t have Go installed, you can do so for your Operating System here: https://go.dev/doc/install

💡

The reason that WASI is needed is because, by default, WASM is for browser-based applications. Because of that, it has no IO which means it wouldn’t be able to interact with things like the network and storage.

Technically, you don’t need WASI, but if you don’t have it, that means you’d have to build an interface yourself. Instead of reinventing the wheel, it makes way more sense to use WASI (especially considering it’s already built into runtimes like Wasmtime).

The first step is to have some code to compile. In this case, you can use the Go (golang) code below which contains:

  1. The main package to ensure it’s the entry point of the application to run.
  2. Import of the fmt package to use the “print to terminal” functionality.
  3. The main function (think functional-based programming) to run the child function.
  4. The child function that has a simple response that gets printed to the terminal.

Save this code somewhere locally and name the file main.go. You don’t have to run it right now.

package main

import "fmt"

func main() {
    wasmTest()
}

func wasmTest() {
    fmt.Println("hello from the WASM beyond!")
}
Enter fullscreen mode Exit fullscreen mode

The next piece is to set up your local instance of Go to use the WASM architecture. To do that, there will be two environment variables:

  • GOOS (Go OS)
  • GOARCH (Go architecture)

Run the following in a terminal that’s in the same directory as the main.go file from the previous step.

GOOS=wasip1 GOARCH=wasm go build -o main.wasm main.go
Enter fullscreen mode Exit fullscreen mode

For example, I have a main.go file in the WASM > appexamples > go directory. After running the command above, I get a main.wasm file.

Image description

You can now run the main.wasm file locally.

wasmtime main.wasm
Enter fullscreen mode Exit fullscreen mode

You should see an output similar to the one below.

Image description

Congrats! You’ve not only installed WASM/WASI as a local runtime but built some code and ran it through the WASM runtime itself.

One thing that you may be interested in taking a look at after this blog post is how WASM/WASI works with Rust. At the time of writing this, Rust seems to be the “most supported language” in the WASM community.

Closing Thoughts

WASM, especially WASI for server-side, is the next iteration in software development. It’s not going to take away things like Docker, Kubernetes, Serverless, etc. because WASM is a runtime and therefore, it needs a place to run.

Top comments (0)