How to Compile Go to WebAssembly (GOOS=js GOARCH=wasm)

Web
To compile Go to WebAssembly, set the environment variables `GOOS=js` and `GOARCH=wasm` before running `go build`, then use a JavaScript runtime like `wasm_exec.js` to execute the resulting `.wasm` binary in a browser.

To compile Go to WebAssembly, set the environment variables GOOS=js and GOARCH=wasm before running go build, then use a JavaScript runtime like wasm_exec.js to execute the resulting .wasm binary in a browser. This process produces a standalone WebAssembly module that can be imported and called from standard JavaScript code.

First, ensure you have the Go toolchain installed (version 1.18+ is recommended for best compatibility). You do not need to install any special Go packages; the standard compiler handles the target. The critical step is setting the environment variables correctly. On Linux or macOS, you can do this inline with your build command:

GOOS=js GOARCH=wasm go build -o main.wasm main.go

On Windows (PowerShell), the syntax differs slightly:

$env:GOOS="js"; $env:GOARCH="wasm"; go build -o main.wasm main.go

This generates a main.wasm file. However, the browser cannot run this file in isolation; it requires the Go runtime shim. You must copy the wasm_exec.js file from your Go installation directory to your web project. The location varies by OS:

  • Linux/macOS: $GOROOT/misc/wasm/wasm_exec.js
  • Windows: %GOROOT%\misc\wasm\wasm_exec.js

Once you have the .wasm file and wasm_exec.js, create an HTML file to load them. The JavaScript must initialize the Go runtime before the WebAssembly module can be instantiated. Here is a minimal working example:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>Go WebAssembly</title>
</head>
<body>
    <h1 id="output"></h1>
    <script src="wasm_exec.js"></script>
    <script>
        const go = new Go();
        WebAssembly.instantiateStreaming(fetch("main.wasm"), go.importObject)
            .then(result => {
                go.run(result.instance);
            });
    </script>
</body>
</html>

Your Go code must include a main function. If you want to write to the browser console or DOM, you can use the syscall/js package. For example, to print "Hello from Go" to the console:

package main

import (
    "syscall/js"
)

func main() {
    js.Global().Get("console").Call("log", "Hello from Go WebAssembly!")
}

Remember that Go's standard library has some limitations in this environment. Packages relying on system calls (like os/exec or net for TCP) often require specific workarounds or are unsupported. Stick to pure logic, JSON handling, or syscall/js for browser interaction. Also, ensure your web server serves the .wasm file with the correct MIME type (application/wasm), or the browser will reject the load.