Building Vugu Programs with TinyGo

Vugu programs can alternatively be compiled using TinyGo, which produces significantly smaller output than the default Go compiler. Many Vugu programs can be compiled with TinyGo to several hundred kilobytes, as opposed to sizes measured in megabytes.

Update Go Generate

Your vugugen Go Generate comment will need to have the -tinygo option added to it, as shown below. The main_wasm.go that is generated is also slightly different so you'll need to remove that file and let it get re-created by vugugen:

package yourpackage

//go:generate vugugen -tinygo

Once that is done, you can proceed with the next steps below.

Making TinyGo Available

The current recommendation (and default) is to run TinyGo compilation via Docker. This means you will need a working Docker installation.

You can also install and use TinyGo on your system without docker. See TinyGo getting started instructions and the NoDocker() option. Please note that as of this writing only the dev branch is compatible with Vugu. When TinyGo version 0.14 is released, that build should work.

Enabling TinyGo Compilation

Although Vugu programs are fundamentally just Go programs, the nature of WebAssembly requires a separate .wasm executable to be built from the source code, in addition to the Go server. To make this simple, Vugu provides some convenience around this Wasm compilation in the devutil package. The basic idea is there is a Compiler with an Execute() method on it, which the development server calls in order to build and then serve the .wasm file. You can swap out the default Compiler implementation from WasmCompiler to TinygoCompiler.

A working Vugu+TinyGo example program can be found here. The relevant portion that needs to change for most programs (for simple examples this lives in devserver.go) is like so:

    wc := devutil.MustNewTinygoCompiler().SetDir(".")
    wc.AddGoGet("go get -u github.com/vugu/vugu github.com/vugu/vjson")
    defer wc.Close()

Some other common options include:

  • For now, external packages required for building need to be explicitly specified with AddGoGet, for example:
    wc.AddGoGet("go get -u -x github.com/vugu/xxhash")
  • Similarly, to override the directory used for specific packages, use AddPkgReplace, example:
    wc.AddPkgReplace("github.com/vugu/vugu", "../vugu")
  • By default Docker is used to call TinyGo. You can use wc.NoDocker() to disable this and have Vugu call the local tinygo executable from your path. At the moment, this results in various additional temporary folder structures being created during compilation to get the GOPATH setup correctly and thus is usually slower. Vugu should be updated soon to remove this limitation and utilize TinyGo's module support.
  • To make file sizes even smaller, you can tell TinyGo to remove debug information with wc.SetTinygoArgs("-no-debug")