[Go WebAssembly] First Wasm Program - Hello World


It is really exciting moment to be able to use Go to do frontend programming. Start from Go 1.11, WebAssembly is supported officially in Go. At the time of this writing, Go 1.11 is not released yet. You can try with go1.11beta2.

As usual, we will say Hello World in our first Go wasm program. Go 1.11 provides syscall/js package to call into JavaScript. Since the author of Go wasm and GopherJS is the same person, it is no surprise that the way to call into JavaScript in Go wasm is similar to that in GopherJS. If you have experiences about GopherJS, you can turn your Go/GopherJS code into Go wasm code just by a few replacement of words in the code. If you want to learn more about GopherJS, search GopherJS in this site.

Because of readability, I am not going to use syscall/js package directly in my code. I update my godom package, a wrapper package for both GopherJS/Go WebAssembly, which make code of DOM manipulation look more like JavaScript. You can install the wrapper for Go wasm by:

$ GOARCH=wasm GOOS=js go get -u github.com/siongui/godom/wasm

Next, we use alert method to display an alert box which says Hello World. It is easy -

package main

import (
      . "github.com/siongui/godom/wasm"
)

func main() {
      Window.Alert("hello world!")
}

We will compile the above code into wasm module. Save above code as alert.go and then run the following command:

$ GOARCH=wasm GOOS=js go build -o alert.wasm alert.go

So far so good, we have our wasm module ready, but how to load the module via JavaScript? This is the most tricky part in my opinion. You need to download the official wasm_exec.js, which loads Go wasm module for you. The following HTML/JavaScript show you how to use the loader:

<!doctype html>
<html>
<head>
  <meta charset="utf-8">
  <title>Go wasm - Hello World</title>
</head>
<body>
  <script src="wasm_exec.js"></script>
  <script>
      const go = new Go();
      let mod, inst;
      WebAssembly.instantiateStreaming(
              fetch("alert.wasm", {cache: 'no-cache'}), go.importObject).then((result) => {
              mod = result.module;
              inst = result.instance;
              run();
      });
      async function run() {
              await go.run(inst);
      };
  </script>
</body>
</html>

Put alert.wasm, wasm_exec.js and above HTML together, open the HTML file with your browser. Visit the following demo to see the final result -

Go Wasm Hello World Demo

The full source code is also available in my GitHub repo.


Tested on:

  • Ubuntu Linux 18.04
  • Go 1.11 beta2
  • Chromium Version 67.0.3396.99 on Ubuntu 18.04 (64-bit)/ Firefox Quantum 61.0.1 (64-bit) on Ubuntu 18.04

References:

[1]














[2]
[3]WebAssembly = Writing JS in Go? • r/golang
[4]A web Go REPL via WebAssembly : golang
[5]Writing a Frontend Web Framework with WebAssembly And Go : golang
[6]Run JavaScript using Otto in Go in WASM in the Browser : golang
[7]This is a WASM-based Vue.js wrapper written in Go : golang
[8]Writing a Frontend Web Framework with WebAssembly And Go : golang
[9]Write Qt for WebAssembly applications entirely in Go and/or JavaScript : golang
[10]Advent 2018: Go and WebAssembly: running Go programs in your browser : golang
[11]Starlight - run python natively inside your Go application : golang