Hyper efficient front end development with web assembly using Go and LLVM

I wanted to write today about my experience with a very cool project named tinygo

Let me first off by saying web assembly in Go has a BIG problem. It’s way too reliant on it’s very bespoke API’s for getting things done. syscalls/js in my opinion is the very definition of the wrong way to go for web assembly:

  • Go devs should NOT learn javascript

I was very happy then when I came across tinygo, compile down a web assembly module and come to found it it makes WAY less assumptions and has a very simple based comment based system for importing functions — something to my knowledge currently impossible in the mainline Go compiler.

tinygo takes advantage of LLVM and is able to reduce web assembly modules to a pretty extreme amount pretty well. What this enables me to do is write very minimal modules like this hello world:

package main//go:export console_log
func console_log(msg string)
//go:export main
func start(){
console_log("hello world")
func main() {}

Compiled down, this module only had 2 import requirements:

  • console_log


  • main

Out of all the options I’ve seen thus far for go web assembly tech, this is about as good as I could have hoped for.

I’ve been writing some libraries that expose some very efficient bindings to DOM manipulation APIs using a generation approached based on browser Web IDL ( standardized descriptions of what functionality browser environments have ).

Instead of making syscalls/JS you have a huge amount of imperative functions you can call to get handles to resources in the DOM and manipulate them. The advantage of this approach is that it is incredibly simple and C like, and requires no special code generation on your part and is entirely tech agnostic. Simply import in the functions you need.

Here’s an example of a canvas app:

package main//go:export global_getWindow
func GetWindow() int32
//go:export Window_get_document
func GetDocument(window int32) int32
//go:export Document_querySelector
func QuerySelector(document int32 ,query string) int32
//go:export HTMLCanvasElement_getContext
func GetContext(element int32,context string) int32
//go:export CanvasRenderingContext2D_fillRect
func FillRect(ctx ,x ,y ,w ,h int32)
//go:export CanvasRenderingContext2D_set_fillStyle
func FillStyle(ctx int32, fillStyle string)
func cstr(s string) string{
return s+"\000"
//go:export main
func start(){
win := GetWindow()
doc := GetDocument(win)
canvas := QuerySelector(doc,cstr("#screen"))
ctx := GetContext(canvas,cstr("2d"))
func main() {}

You can see this working live here

Overall i’m very excited to have one more tool in my toolbelt to create low level web assembly. Maybe with a bit of work, tinygocan generate a bit cleaner and be as solid as Rust is in the next tech platform of the web.

Data Engineer, Code Philosopher, & Robot Psychologist

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store