01 | 01a | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09

08 — WASM Demo

A full multi-series chart rendered entirely in the browser via WebAssembly. The gogal library compiles to WASM with zero changes — same NewLineChart, Add, RenderString API. No server required.

Multi-series chart rendered via WASM
Full static chart — identical output whether server-rendered or WASM

The WASM entry point

A main_wasm.go file (build-tagged js && wasm) exports a goRender() function that returns SVG HTML. The JS glue calls it once on load.

//go:build js && wasm

package main

import (
    "syscall/js"
    "codeberg.org/hum3/gogal"
)

func render() string {
    chart := gogal.NewLineChart(
        gogal.WithVariant(gogal.Static),
        gogal.WithTitle("Weather — 15 June 2024 (WASM)"),
        gogal.WithGrid(true),
        gogal.WithSmooth(true),
    )
    chart.Add("Temperature (°C)", temp)
    chart.Add("Humidity (%)", humidity)
    svg, _ := chart.RenderString()
    return svg
}

func main() {
    js.Global().Set("goRender", js.FuncOf(func(this js.Value, args []js.Value) any {
        return render()
    }))
    js.Global().Call("wasmReady")
    select {}
}
Same API, different target — the chart code is identical to server-rendered examples. Only the entry point differs: instead of Render(w) to an HTTP response, you call RenderString() and return it to JavaScript.
Build tagsmain.go has //go:build !js (server mode) and main_wasm.go has //go:build js && wasm. The Go compiler picks the right file based on GOOS=js GOARCH=wasm.

Building

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

Or via the Taskfile:

task docs:build-wasm
Binary size — a gogal WASM binary is ~2.6 MB. Since gogal has zero dependencies, the binary is mostly the Go runtime. TinyGo could reduce this further (not yet tested).

JavaScript glue

window.wasmReady = function() {
    document.getElementById('output').innerHTML = goRender();
};

const go = new Go();
WebAssembly.instantiateStreaming(fetch('main.wasm'), go.importObject)
    .then(result => go.run(result.instance));

Full source on Codeberg


Running it

Server mode:

task example:08

WASM mode: open docs/08_wasm/demo.html in a browser (needs an HTTP server for WASM loading).


Back to examples | Source on Codeberg | API docs