Quick Tutorial: Write Go, Run WASM!
Tags: go, webassembly
Published: 2018-08-06 16:01:07

---
title: Quick Tutorial: Write Go, Run WASM!
published: true
description: Demonstrate how to compile Go source code into WASM and execute in the browser.
tags: go, webassembly
---

Before Go 1.11 gets released, which introduces an experimental port to WebAssembly (WASM for short), I'm going to demonstrate how to compile Go source code into WASM and execute in the browser!

Here are the steps:
1. Setup `go1.11beta3`
2. Compile Go to WASM
3. Use HTML and JavaScript to load WASM
4. Spin up a web server
5. Open the website!

### Step 1: Setup `go1.11beta3`
Although we need Go version 1.11 which is still in beta (due in August!), because Go is open-source we can just download the latest beta instead.

https://github.com/golang/go/releases/tag/go1.11beta3

```sh
$ go get golang.org/dl/go1.11beta3
$ go1.11beta3 download
# => Success. You may now run 'go1.11beta3'
```

### Step 2: Compile Go to WASM
We can now write Go! The plan is to print the classic `hello, Go/WASM!` but in the browser––in the developer console.

```go
// main.go
package main

import "fmt"

func main() {
    fmt.Println("hello, Go/WASM!")
}
```

To compile our program from Go to WASM, we use the command `go build`.

**Note:** We need to tell Go to compile for the web and not the default environment; our computer. So we need to set the environmental variables `GOOS=js` and `GOARCH=wasm` to target the web.

```sh
$ GOOS=js GOARCH=wasm go1.11beta3 build -o test.wasm main.go
```

### Step 3: Use HTML and JavaScript to load WASM
This step isn't difficult; the Go team has prepared some files for us to experiment with.

```sh
# -s == silent mode
# -O == output mode
$ curl -sO https://raw.githubusercontent.com/golang/go/master/misc/wasm/wasm_exec.html
$ curl -sO https://raw.githubusercontent.com/golang/go/master/misc/wasm/wasm_exec.js
```

### Step 4: Spin up a web server
Now we need to spin up a simple web server to serve some static assets. This is just a few lines of code:

```go
// server.go
package main

import (
    "flag"
    "log"
    "net/http"
)

func main() {
    port := flag.String("port", "8000", "port")
    flag.Parse()
    log.Fatal(http.ListenAndServe(":"+*port, http.FileServer(http.Dir("."))))
}

```

Let's start it! Cheers!

```sh
$ go1.11beta3 run server.go

# or to run on a different port:
# $ go1.11beta3 run -port=8080 server.go
```

### Step 5: Open the website!
Open `localhost:8000/wasm_exec.html`!

**Note:** A 'Run' button (at the top left) will appear disabled until the compiled WASM is loaded.

Once the 'Run' button is enabled, open the console and press the button!

See `hello, Go/WASM!`??

Congratulations! 🎉

You've just compiled, loaded, and run a Go program via WASM!

Is that true?

Why don't you confirm that `Content-Type` is `application/wasm` in the response header of `test.wasm`? ;)

### Acknowledgements
Thank you [ZAYDEK](https://twitter.com/username_ZAYDEK) for recommending me to translate [my article](https://qiita.com/cia_rana/items/bbb4112b480636ab9d87) into English and reviewing this article. 

### References
- [サクッと Go → WebAssembly を試す(Original article in Japanese)](https://qiita.com/cia_rana/items/bbb4112b480636ab9d87)
- [Go and wasm: generating and executing wasm with Go - Gopher Academy Blog Community Contributed Go Articles and Tutorials](https://blog.gopheracademy.com/advent-2017/go-wasm/)