Working with WebAssembly and Go: From A to Z — Complete Guide

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Introduction to WebAssembly and Go

\n\n

WebAssembly (WASM) is a low-level binary format that allows running code written in languages other than JavaScript directly in the browser. Go (Golang) with its powerful standard library and excellent concurrency support has become one of the best candidates for compiling to WASM. In this article, we will walk through the process of working with WebAssembly in Go, from installing tools to deploying a complete solution.

\n\n

Modern web applications require high performance, and WebAssembly provides the ability to run code written in Go at near-native speed. This opens doors for porting heavy computations, game engines, and data processing systems directly into the browser.

\n\n

Environment Setup and Configuration

\n\n

Before starting, make sure you have the latest version of Go (1.21+) installed. For working with WebAssembly, you will need the tinygo compiler (optional, for reducing binary size) or the standard go build.

\n\n

Basic Requirements

\n
    \n
  • Go 1.21 or newer
  • \n
  • A browser with WebAssembly support (Chrome, Firefox, Safari, Edge)
  • \n
  • Basic understanding of JavaScript
  • \n
\n\n

Setting Environment Variables

\n
# Set GOOS and GOARCH for cross-compilation\nexport GOOS=js\nexport GOARCH=wasm\n\n# Verify everything is configured correctly\ngo env GOOS GOARCH\n# Should see: js wasm
\n\n

You also need to copy the wasm_exec.js support file from the Go standard library:

\n
cp "$(go env GOROOT)/misc/wasm/wasm_exec.js" ./
\n\n

Writing and Compiling Your First WASM Module

\n\n

Let's create a simple module that will export a function for adding two numbers and display a message in the browser console.

\n\n

Go Code

\n
package main\n\nimport "syscall/js"\n\nfunc add(this js.Value, args []js.Value) interface{} {\n    if len(args) < 2 {\n        return "Error: need two arguments"\n    }\n    a := args[0].Int()\n    b := args[1].Int()\n    return a + b\n}\n\nfunc main() {\n    // Register the function in the global object\n    js.Global().Set("goAdd", js.FuncOf(add))\n    \n    // Block the goroutine to prevent WASM from exiting\n    select {}\n}
\n\n

Compiling to WASM

\n
go build -o main.wasm main.go
\n\n

After compilation, you will get a main.wasm file approximately 2-3 MB in size (with the standard compiler). For production, it is recommended to use TinyGo, which reduces the size to 10-50 KB.

\n\n

Integration with JavaScript and HTML

\n\n

Now let's create an HTML page that loads and uses our WASM module.

\n\n

HTML Template

\n
<!DOCTYPE html>\n<html>\n<head>\n    <meta charset="utf-8">\n    <title>Go WebAssembly Demo</title>\n</head>\n<body>\n    <h1>Go + WebAssembly</h1>\n    <input type="number" id="num1" value="10">\n    <input type="number" id="num2" value="20">\n    <button onclick="calculate()">Add</button>\n    <p>Result: <span id="result">0</span></p>\n\n    <script src="wasm_exec.js"></script>\n    <script>\n        const go = new Go();\n        \n        WebAssembly.instantiateStreaming(\n            fetch("main.wasm"), \n            go.importObject\n        ).then((result) => {\n            go.run(result.instance);\n            console.log("WASM loaded!");\n        });\n\n        function calculate() {\n            const a = parseInt(document.getElementById('num1').value);\n            const b = parseInt(document.getElementById('num2').value);\n            const result = goAdd(a, b);\n            document.getElementById('result').textContent = result;\n        }\n    </script>\n</body>\n</html>
\n\n

Working with Memory and Complex

Blogs

Book Recommendations