Run Golang App in Browser using web assembly

Run Golang App in Browser using web assembly

Here we will write a simple website and run a golang application inside a browser using web assembly .

WebAssembly is a new type of code that can be run in modern web browsers — it is a low-level assembly-like language with a compact binary format that runs with near-native performance and provides languages such as C/C++, C# and Rust with a compilation target so that they can run on the web. It is also designed to run alongside JavaScript, allowing both to work together.

In a Nutshell

WebAssembly has huge implications for the web platform — it provides a way to run code written in multiple languages on the web at near native speed, with client apps running on the web that previously couldn't have done so.

WebAssembly is designed to complement and run alongside JavaScript — using the WebAssembly JavaScript APIs, you can load WebAssembly modules into a JavaScript app and share functionality between the two. This allows you to take advantage of WebAssembly's performance and power and JavaScript's expressiveness and flexibility in the same apps, even if you don't know how to write WebAssembly code.

First

Build/download a golang project with UI . I recommend Fyne UI / Gio UI library of golang . Here i am using a Gio opensource application https://git.sr.ht/~eliasnaur/gio-example/tree/main/kitchen/kitchen.go

. you can use the same code or any other

1. Build your main.go file to main.wasm

use this command to build main.wasm file from main.go file

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

you can use tinygo to build main.wasm file, it will create very small wasm file.

tinygo build -o main.wasm -target wasm ./main.go

2. We need a wasm run time

Implementation of wasm_exec.js for Go Wasm runtimes

wasmexec

wasmexec is runtime-agnostic implementation of Go’s wasm_exec.js in Go. It currently has import hooks for wasmer, wasmtime and wazero. Each runtime-dedicated package has its own example of an implementation that can run any of the examples.

This implementation was made possible by allowing me to peek at mattn’s implementation as well as Vedhavyas Singareddi’s go-wasm-adapter.

Copy the wasm_exec.js from golang compiler .

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

or , your will find it in official github repository of Golang

https://github.com/golang/go/blob/master/misc/wasm/wasm_exec.js

3. Write a sample html file where you will import the wasm_exec.js & using WebAssembly.instantiateStreaming fetch main.go

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>my wasm</title>
    <link rel="icon" type="image/ico" href="favicon.ico" />
    <script src="wasm_exec.js"> </script>
    <script >
    const go =new Go()
    WebAssembly.instantiateStreaming(
        fetch("main.wasm"), 
        go.importObject
    ).then(result=>go.run(result.instance)) 
    // OR

    // const go =new Go()
    // const result = await WebAssembly.importStreaming(
    //     fetch("main.wasm"),
    //     go.importObject
    // )
    // go.run(result.instance)
    // init()

    </script>

</head>
<body>

</body>
</html>

For simply host this code use http-server . run npm install --global http-server for install it globally . than simply run http-server . in the project directory.

Project Directory should contain these index.html , wasm_exec.js , main.wasm files .

As a result ,I got this output . and it ran perfectly

Screenshot from 2022-07-26 18-44-16.png

if you had hard time to configure see this repository

https://github.com/skshahriarahmedraka/WebAssembly-Golang-example/tree/main/5.Gio