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.