Working with WebAssembly and Go: Building Fast Web Applications

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



WebAssembly (Wasm) is a low-level binary instruction format that runs in the browser at near-native speed. Combined with the Go language (Golang), you get a powerful tool for creating high-performance web applications. Go compiles to WebAssembly, allowing you to bring complex computations, algorithms, and even games directly into the browser without sacrificing performance.



In this article, we will cover how to set up the environment, write a simple Go module, compile it to Wasm, and integrate it with JavaScript. You will learn about key packages, limitations, and best practices.



Setting up the environment for compiling Go to Wasm



Installing Go and WebAssembly dependencies



First of all, make sure you have Go version 1.11 or newer installed (1.21+ is recommended). WebAssembly support is built-in. The environment variables GOOS=wasm GOARCH=wasm are used for compilation.



You will also need the support file wasm_exec.js, which comes bundled with Go. Copy it to the project root:



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


Project structure



Let's create a simple structure:



my-wasm-app/├── main.go├── wasm_exec.js├── index.html└── main.wasm (will be created after compilation)


Writing a Go module for WebAssembly



Simple example: addition function



Create a file main.go with the following content:



package main

import ( "syscall/js")

func add(this js.Value, args []js.Value) interface{} { if len(args) < 2 { return 0 } a := args[0].Int() b := args[1].Int() return a + b}

func main() { c := make(chan struct{}, 0)

js.Global().Set("goAdd", js.FuncOf(add))

<-c}


Here we use the syscall/js package to interact with JavaScript. The add function takes two arguments and returns their sum. The channel c blocks program termination so that the module remains active.



Compiling to Wasm



Run the command:



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


The result will be a main.wasm file approximately 1–2 MB in size (for this simple example). In production, use the -ldflags="-s -w" flag to reduce the size.



Integration with HTML and JavaScript



Creating an HTML page



Create a file index.html:



<!DOCTYPE html><html lang="ru"><head>    <meta charset="UTF-8">    <title>Go + WebAssembly</title>    <script src="wasm_exec.js"></script></head><body>    <h2>Calculator in Go in the browser</h2>    <input type="number" id="num1" value="5">    <input type="number" id="num2" value="10">    <button onclick="calculate()">Add</button>    <p>Result: <span id="result">0</span></p>

<script> const go = new Go(); WebAssembly.instantiateStreaming(fetch("main.wasm"), go.importObject) .then((result) => { go.run(result.instance); console.log("WebAssembly module loaded"); });

function calculate() { const a = parseInt(document.getElementById('num1').value); const b = parseInt(document.getElementById('num2').value); const sum = goAdd(a, b); document.getElementById('result').innerText = sum; } </script></body></html>


Note: the goAdd function becomes global thanks to the js.Global().Set("goAdd", ...) call in the Go code.



Running a local server

Blogs

Book Recommendations