Pushing the button, the function implemented in Go is called, and it updates the value of text.

$ go version
go version go1.18 darwin/amd64
Go can refer variables and call functions in js with syscall/js package. By breaking changes of Go 1.12, NewCallback() is renamed to FuncOf(). The function must return the value that has a type js.ValueOf() expects, so if returns a struct, an error occurs.
package main
import (
"strconv"
"syscall/js"
)
func increment(this js.Value, args []js.Value) any {
counter := js.Global().Get("document").Call("getElementById", "counter")
counterValue, err := strconv.ParseInt(counter.Get("textContent").String(), 10, 64)
if err != nil {
return map[string]any{"error": err.Error()}
}
counterValue += int64(args[0].Int())
counter.Set("textContent", counterValue)
return map[string]any{"message": counterValue}
}
func main() {
js.Global().Set("goIncrement", js.FuncOf(increment))
select {} // keep running
}
Build .wasm file with GOOS=js, GOARCH=wasm.
.wasm files in Go are usually large size, this file is also 1.3M.
.wasm files in Go tend to be large. This file is 1.3MB.
TinyGo can make it significantly smaller at 165KB.
$ GOOS=js GOARCH=wasm go build -o main.wasm main.go
$ tinygo build -o wasm.wasm -target wasm ./main.go
Load wasm_exec.js that exists in the official repository, and compile and load the .wasm file with WebAssembly.instantiateStreaming.
<html>
<head>
<script src="wasm_exec.js"></script>
<script>
const go = new Go();
WebAssembly.instantiateStreaming(fetch("main.wasm"), go.importObject).then((result) => {
go.run(result.instance);
});
function increment(value) {
ret = goIncrement(value)
console.log(ret)
}
</script>
</head>
<body>
<div id="counter">0</div>
<button onClick="increment(1)">+1</button>
</body>
Start a server that delivers these files, and check the operation.
$ npx http-server
$ open localhost:8080/index.html
References
Go WebAssembly Tutorial - Building a Calculator Tutorial | TutorialEdge.net
javascript - Golang’s syscall/js js.NewCallback is undefined - Stack Overflow
How do WebAssembly binaries compiled from different languages compare in size? - Stack Overflow