WebAssembly with Go
WebAssembly (often abbreviated as Wasm) is a binary instruction format for a stack-based virtual machine. 1
WebAssembly code is compiled into a binary format executed directly by the browser’s virtual machine rather than interpreted like traditional JavaScript code.
It runs in a sandboxed environment, preventing it from accessing sensitive user data or interfering with other web page parts.
WebAssembly is also designed to be portable, meaning that it can be used across a wide range of platforms and devices. This makes it an ideal tool for building web applications that need to work seamlessly across different devices and operating systems.
Write WebAssembly With Go
WebAssembly is a binary format that allows for code deployment on the web. It is designed to be fast, efficient, and secure and can be used with various programming languages, including Go.
To use WebAssembly with Go, you must compile your Go code to WebAssembly. After compiling the code, it can be used just like any other JavaScript code in the web application.
go mod init wasmcounter
// main.go
package main
import "fmt"
func main() {
fmt.Println("Hello from Go WebAssembly!")
}
Compile our code into wasm format. Use two flags GOOS=js
and GOARCH=wasm
for the Go compiler.
GOOS=js GOARCH=wasm go build -o main.wasm main.go
# copy the `wasm_exec.js` with this command:
cp "$(go env GOROOT)/misc/wasm/wasm_exec.js" .
<!-- index.html -->
<html>
<head>
<meta charset="utf-8" />
<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>
</head>
<body>
<h1>Hello WebAssembly</h1>
</body>
</html>
# to serve the page
python3 -m http.server 6161
# open the page
open http://localhost:6161
A Counter App
// main.go
package main
import (
"fmt"
"syscall/js"
)
func main() {
c := make(chan bool)
fmt.Println("Hello from Go WebAssembly!")
js.Global().Set("increment", js.FuncOf(increment))
js.Global().Set("decrement", js.FuncOf(decrement))
<-c
}
var count int
func increment(this js.Value, args []js.Value) interface{} {
count++
return count
}
func decrement(this js.Value, args []js.Value) interface{} {
count--
return count
}
GOOS=js GOARCH=wasm go build -o main.wasm main.go
# copy the `wasm_exec.js` with this command:
cp "$(go env GOROOT)/misc/wasm/wasm_exec.js" .
<!-- index.html -->
<html>
<head>
<meta charset="utf-8" />
<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>
</head>
<body>
<h1>WebAssembly in Go</h1>
<button id="increment" onclick="incrementCounter()">Increment</button>
<span id="count">0</span>
<button id="decrement" onclick="decrementCounter()">Decrement</button>
</body>
<script>
const incrementCounter = () => {
const count = increment()
setCounterValue(count)
}
const decrementCounter = () => {
const count = decrement()
setCounterValue(count)
}
const setCounterValue = (value) => {
const countEl = document.getElementById("count")
countEl.textContent = value
}
</script>
</html>
# to serve the page
python3 -m http.server 6161
# open the page
open http://localhost:6161