Written by: ekwoster.dev on Sun Sep 14

๐Ÿ”ฅ Why TinyGo Might Be the Future of Embedded WebAssembly & How To Get Started Today

๐Ÿ”ฅ Why TinyGo Might Be the Future of Embedded WebAssembly & How To Get Started Today

Cover image for ๐Ÿ”ฅ Why TinyGo Might Be the Future of Embedded WebAssembly & How To Get Started Today

๐Ÿ”ฅ Why TinyGo Might Be the Future of Embedded WebAssembly & How To Get Started Today

If you've ever tried bringing Go to the WebAssembly (WASM) world or into an embedded device, you've probably realized something pretty quickly: Go's runtime is too big. But what if I told you there's a tiny compiler that strips Go down to its minimalist core, letting you create blazing-fast binaries that run on microcontrollers and the browser?

Enter TinyGo โ€” a small Go compiler built for WebAssembly and microcontrollers. It's fast, fun, and solves real-world performance and portability problems in ways most devs haven't realized yet.

This blog post peels the curtain back on TinyGo's power, shows it outperforming JS in some browser scenarios (yes, really), and walks through building a real embedded WebAssembly example with practical code. Let's dive in. โš™๏ธ


๐Ÿค” What is TinyGo?

โ€œTinyGo is a Go compiler for small places. Microcontrollers, WebAssembly (WASM), and command-line tools. Own the binary size.โ€

Built on LLVM, TinyGo compiles a subset of Go into highly efficient machine code for microcontrollers and WASM. It's perfect for developers who love Goโ€™s syntax and want to bring its simplicity to:

  • Arduino, STM32, micro:bit, and more
  • Browser via WebAssembly
  • CLI tools with ultra-low footprint

TL;DR: It brings the Go experience to devices and environments where regular Go simply cannot go (pun intended).


๐Ÿง  Use Case: WASM-powered Sensor Dashboard Embedded in the Browser

Letโ€™s build something real.

Goal: Create a tiny sensor simulator in TinyGo WASM that emits live temperature data to the browser, where JS then renders it.

Imagine this powering low-cost IoT dashboards entirely via WebAssembly, cutting down JavaScript's runtime overhead.


๐Ÿš€ Step 1: Install TinyGo

brew tap tinygo-org/tools
brew install tinygo

Or download for your OS.

Test version:

tinygo version
# tinygo version 0.xx.x ...

๐Ÿงช Step 2: Write Go Sensor Code

File: main.go

package main

import (
    "machine"
    "math/rand"
    "time"
    "syscall/js"
)

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

    js.Global().Set("readSensor", js.FuncOf(func(this js.Value, args []js.Value) interface{} {
        temp := readFakeSensor()
        return js.ValueOf(temp)
    }))

    <-c // Block forever
}

func readFakeSensor() float64 {
    rand.Seed(time.Now().UnixNano())
    return 20 + rand.Float64()*10 // Simulate 20ยฐโ€“30ยฐC
}

This example defines a readSensor() function exposed to the browser, simulating lightweight sensor data generation.


๐Ÿ—๏ธ Step 3: Compile to WASM

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

Also copy the WASM exec JS glue code:

cp $(tinygo env TINYGOROOT)/targets/wasm_exec.js ./

๐Ÿ–ผ๏ธ Step 4: Simple HTML Dashboard

HTML: index.html

<!DOCTYPE html>
<html>
<head>
  <title>TinyGo Sensor Dashboard</title>
  <script src="wasm_exec.js"></script>
  <style>body {font-family: sans-serif; margin: 2rem;}</style>
</head>
<body>
  <h1>๐Ÿ”ฅ Temperature Sensor (Simulated)</h1>
  <p>Current Temp: <span id="temp">--</span> ยฐC</p>

  <script>
    const go = new Go();
    WebAssembly.instantiateStreaming(fetch("main.wasm"), go.importObject).then((result) => {
      go.run(result.instance);
      setInterval(() => {
        const temp = readSensor();
        document.getElementById("temp").innerText = temp.toFixed(2);
      }, 1000);
    });
  </script>
</body>
</html>

Launch a local server:

python3 -m http.server 8000

Open in browser:

http://localhost:8000

Voila! A live temperature reading embedded via TinyGo-WASM.


๐Ÿ“‰ Is TinyGo Actually Smaller Than JavaScript?

Yes. Super yes.

Letโ€™s run ls -lh main.wasm

# -rw-r--r--  34K main.wasm

Compare this to React + Parcel + Redux = 600KB+, not accounting for the runtime itself.

More importantly, it runs with no runtime garbage collector pauses (WASM land remembers everything)


๐Ÿ”ฉ Real-World Use Cases

  • IoT dashboards compiling directly to the browser.
  • WASM CLI tools under 100KB.
  • Machine control interfaces with touchscreens (e.g., ESP32 with display).
  • React-free dashboards where device constraints matter.

โš–๏ธ TinyGo vs Go: Whatโ€™s Missing?

TinyGo isn't a full replacement for Go. Be aware:

  • No full reflection support
  • Limited or no goroutines (uses async strategies instead)
  • Smaller standard lib (but growing!)
  • Garbage collection is optional/static

But itโ€™s evolving fast, and for use cases in embedded and client-side WASM, itโ€™s more than enough.


๐Ÿง  Conclusion

TinyGo is less about replacing Go and more about unlocking it in domains traditionally owned by C or JavaScript. ๐Ÿ˜ฎ

Whether for microcontrollers or WebAssembly UIs on the edge, TinyGo is a weapon no fullstack dev should ignore โ€” especially when working across browser + hardware.


๐Ÿ“š Resources


โค๏ธ Like this post?

Follow for more deep-dive explorations of the future of dev tools โ€” before they go mainstream!


๐Ÿ”ง If you need help building edge-capable WASM/PWA dashboards or embedded systems, we offer custom fullstack development.