DEV Community

Cover image for ๐Ÿ’ก The Hidden Power of TinyGo: Run Go on Microcontrollers Faster Than C? Here's the Shocking Truth!
Yevhen Kozachenko ๐Ÿ‡บ๐Ÿ‡ฆ
Yevhen Kozachenko ๐Ÿ‡บ๐Ÿ‡ฆ

Posted on • Originally published at ekwoster.dev

๐Ÿ’ก The Hidden Power of TinyGo: Run Go on Microcontrollers Faster Than C? Here's the Shocking Truth!

๐Ÿ’ก The Hidden Power of TinyGo: Run Go on Microcontrollers Faster Than C? Here's the Shocking Truth!

In the world of embedded systems, two things always reign supreme: performance and memory efficiency. The common perception has always been to write low-level embedded code in C or even Assembly. But what if I told you that you could write embedded software in Go and compile it down to a tiny, lightning-fast binary that runs on microcontrollers with less than 256KB of Flash and 64KB of RAM?

Welcome to TinyGo.

TinyGo is a compiler for the Go programming language, designed to target resource-constrained systems like microcontrollers, WebAssembly (WASM), and even command-line tools with an absolutely minimal footprint. Sounds crazy? In this deep-dive post, weโ€™re going to:

  • Demystify TinyGo and how it compares to regular Go and C
  • Explore real-world hardware examples
  • Understand memory, performance considerations, and limitations
  • Build and flash a real microcontroller LED blink example in TinyGo

Letโ€™s dive in! ๐Ÿš€


๐Ÿงฌ What Is TinyGo?

TinyGo is built on top of LLVM and provides a Go frontend that supports a subset of the Go standard library. It compiles Go code into drastically smaller binaries suitable for microcontrollers and WebAssembly platforms.

TinyGo is meant for:

  • Embedded systems (Arduino, STM32, micro:bit, NRF52)
  • WebAssembly applications
  • Building CLI tools with small executable size

โž• Bonus: TinyGo produces WASM binaries as small as 100KB, making Go a frighteningly compelling case for frontend performance optimization.


โš”๏ธ TinyGo vs C: The Showdown

Metric C Regular Go TinyGo
Compilation Speed Fast Fast Moderate
Binary Size (Hello) ~1 KB ~2.1 MB ~12 KB
MCU Support Native โŒ โœ…
Garbage Collection No Yes Optional/Manual
Toolchain Ecosystem Mature Mature Growing

The binary size alone is enough reason to consider TinyGo when you want a high-level language but low-level hardware support.


๐Ÿ”Œ Hello World on a Microcontroller (Blink an LED!)

Letโ€™s write our first TinyGo program that blinks an LED on an Arduino board (e.g., Arduino Uno).

๐Ÿงฐ Prerequisites

  • Install TinyGo
  • Arduino UNO or compatible board
  • USB cable
# Install TinyGo
brew tap tinygo-org/tools
brew install tinygo

# Confirm installation
tinygo version
Enter fullscreen mode Exit fullscreen mode

๐Ÿ”ง Code: Blink.go

package main

import (
    "machine"
    "time"
)

func main() {
    led := machine.LED
    led.Configure(machine.PinConfig{Mode: machine.PinOutput})

    for {
        led.High()           // Turn LED on
        time.Sleep(time.Second)
        led.Low()            // Turn LED off
        time.Sleep(time.Second)
    }
}
Enter fullscreen mode Exit fullscreen mode

๐Ÿš€ Flash to Hardware

tinygo flash -target=arduino examples/blink.go
Enter fullscreen mode Exit fullscreen mode

Congratulations! You just wrote and flashed a Go program to a microcontroller! ๐Ÿ’ฅ


๐Ÿฌ Bonus: TinyGo + WebAssembly for Ultra-Light Frontend Bundles

TinyGo is not just for microcontrollers. Hereโ€™s what a simple DOM manipulation app in TinyGo looks like.

index.html

<!DOCTYPE html>
<html>
  <body>
    <button id="btn">Click me</button>
    <script src="wasm_exec.js"></script>
    <script>
      const go = new Go();
      WebAssembly.instantiateStreaming(fetch("main.wasm"), go.importObject).then(result => {
        go.run(result.instance);
      });
    </script>
  </body>
</html>
Enter fullscreen mode Exit fullscreen mode

main.go

package main

import (
    "syscall/js"
)

func main() {
    document := js.Global().Get("document")
    btn := document.Call("getElementById", "btn")
    btn.Call("addEventListener", "click", js.FuncOf(func(this js.Value, p []js.Value) interface{} {
        js.Global().Call("alert", "Hello from TinyGo!")
        return nil
    }))

    done := make(chan struct{}, 0)
    <-done // Prevent exiting
}
Enter fullscreen mode Exit fullscreen mode

Compile to WASM

tinygo build -o main.wasm -target wasm ./main.go
Enter fullscreen mode Exit fullscreen mode

๐ŸŽ‰ Now you have a lightweight frontend app written in TinyGo that can be run inside the browser!


๐Ÿ“Š Common Pitfalls When Using TinyGo

  1. Missing Standard Library Support: TinyGo doesnโ€™t support all of Goโ€™s standard library. Be mindful.
  2. Limited Reflection: No fancy JSON marshaling with struct tagsโ€”use minimal dependencies.
  3. Garbage Collection Limitations: GC is limited and can lead to subtle issues on devices with limited RAM.
  4. Peripheral Support Limitations: Not all microcontroller peripherals are fully supported. Check your chipset compatibility on the TinyGo Targets page.

๐Ÿง  Final Thoughts: Why It Matters

TinyGo gives you a superpower: write high-level, garbage-collected, readable code that runs unbelievably well on constrained devices.

What used to take hundreds of lines and hours in C can be built in a few minutes using TinyGo. Better yet, you can share business logic across microcontrollers and WebAssembly targets in a single codebase written in Go.

In a world where IoT is growing and frontend performance matters more than ever, TinyGo is a powerful tool you probably havenโ€™t triedโ€”but absolutely should.


๐Ÿ”— Resources


โœ… TLDR

  • TinyGo is a Go compiler optimized for microcontrollers and WASM
  • It generates binaries significantly smaller than standard Go
  • Ideal for โ˜ IoT, ๐Ÿง  Edge AI, and ๐Ÿ’ป WebAssembly
  • Try writing a LED blinker or browser app todayโ€”Go has never been so small

๐Ÿš€ In a world of bloated runtimes, TinyGo gives you minimalism with power.


๐Ÿ’ผ If you're looking to explore or build innovative hardware or browser-based projects using TinyGo, we offer tailored Research and Development services to bring your ideas to life!

Top comments (0)