100 Helloslanguages
Home / Languages / TinyGo

TinyGo

2018
systemsimperativeconcurrent
docker run --rm --platform="linux/amd64" 100hellos/tinygo:latest

TinyGo is a Go compiler for small places. It's designed to bring the Go programming language to microcontrollers, WebAssembly, and other environments where traditional Go is too resource-intensive.

About TinyGo

TinyGo is not just a subset of Go - it's a completely different compiler implementation built on LLVM that targets small devices and embedded systems. While regular Go is excellent for servers and desktop applications, TinyGo excels in:

  • Microcontrollers: Arduino, Raspberry Pi Pico, micro:bit, ESP32, and many others
  • WebAssembly: Creating small, fast WASM modules
  • Embedded Systems: IoT devices, sensors, and real-time applications
  • Static Binaries: Producing tiny, statically linked executables

Key Differences from Regular Go

Smaller Runtime

TinyGo implements a much smaller runtime compared to standard Go:

  • No garbage collector (or a very minimal one depending on target)
  • Smaller standard library footprint
  • Direct hardware access for microcontrollers

Size Comparison

Where a regular Go "Hello World" might be 2MB+, TinyGo can produce:

  • Microcontrollers: 1-10KB depending on target
  • WebAssembly: 1-50KB
  • Linux executables: 10-100KB

Compilation Targets

TinyGo supports dozens of microcontroller targets out of the box:

# Examples of supported targets
tinygo flash -target=arduino main.go
tinygo flash -target=microbit main.go
tinygo flash -target=pico main.go
tinygo build -target=wasm main.go

Language Features

TinyGo supports most Go language features including:

  • Goroutines (limited on some targets)
  • Channels
  • Interfaces
  • Closures
  • Most standard library packages (subset)

Note: Some advanced features like reflection and the full net/http package may not be available on all targets.

Real-World Applications

TinyGo is used in production for:

  • IoT Sensors: Temperature, humidity, motion sensors
  • Robotics: Motor controllers, sensor integration
  • Wearables: Fitness trackers, smartwatches
  • Industrial Control: PLCs, automation systems
  • Edge Computing: Lightweight data processing

Development Workflow

Unlike regular Go development, TinyGo often involves:

  1. Target Selection: Choosing your hardware platform
  2. Hardware Abstraction: Using machine package for GPIO, I2C, SPI
  3. Size Optimization: Keeping code minimal for resource constraints
  4. Cross-Compilation: Building for different architectures

Example microcontroller code:

package main

import (
    "machine"
    "time"
)

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

    for {
        led.High()
        time.Sleep(500 * time.Millisecond)
        led.Low()
        time.Sleep(500 * time.Millisecond)
    }
}

Further Exploration

TinyGo opens up the world of embedded programming to Go developers, bringing familiar syntax and powerful features to the smallest of devices.

Hello World

package main

// BEGIN_FRAGLET
import "fmt"

func main() {
	fmt.Println("Hello World!")
}
// END_FRAGLET

Coding Guide

Language Version

TinyGo 0.38.0 (Go subset)

Execution Model

  • Compiled language using tinygo build
  • Code is compiled to a binary, then executed
  • Standard Go execution model with main() function in main package
  • TinyGo is a subset of Go optimized for small targets (microcontrollers, WebAssembly, etc.)

Key Characteristics

  • Statically typed (Go subset)
  • Case-sensitive (exported identifiers start with uppercase)
  • Garbage collected
  • Strong typing with type inference (:= operator)
  • Package-based module system
  • Built-in concurrency primitives (goroutines, channels) - limited support
  • No classes (uses structs and methods instead)
  • Functions are first-class citizens
  • Important: TinyGo supports a subset of Go's standard library and features

Fragment Authoring

Write valid TinyGo code. The package main declaration is pre-provided. Your fragment should include import declarations and define func main() as the entry point.

Available Packages

The template includes the standard library package:

  • fmt - Formatted I/O (Println, Printf, Sprintf)

Additional standard library packages may be available (TinyGo subset):

  • strings - String manipulation
  • strconv - String conversions
  • os - Operating system interface (limited)
  • math - Mathematical functions
  • time - Time operations (limited)
  • sync - Synchronization primitives (limited)

Note: TinyGo supports a subset of Go's standard library. Some packages and features may not be available.

Common Patterns

  • Print: fmt.Println("message") or fmt.Printf("format %s\n", value)
  • Variables: var x int = 10 or x := 10 (type inference)
  • Functions: func add(a, b int) int { return a + b }
  • Structs: type Person struct { Name string; Age int }
  • Methods: func (p Person) String() string { return fmt.Sprintf("%s (%d)", p.Name, p.Age) }
  • Slices: numbers := []int{1, 2, 3} or numbers := make([]int, 0, 10)
  • Maps: m := make(map[string]int) or m := map[string]int{"a": 1}
  • Basic loops: for i := 0; i < 10; i++ { ... } or for _, num := range numbers { ... }

Examples

// Simple output
func main() {
    fmt.Println("Hello from fragment!")
}

// Variables and calculations
func main() {
    a := 5
    b := 10
    fmt.Printf("Sum: %d\n", a+b)
}

// Functions
func add(a, b int) int {
    return a + b
}

func main() {
    result := add(5, 10)
    fmt.Printf("5 + 10 = %d\n", result)
}

// Slices and loops
func main() {
    numbers := []int{1, 2, 3, 4, 5}
    sum := 0
    for _, num := range numbers {
        sum += num
    }
    fmt.Printf("Sum: %d\n", sum)
}

// Structs and methods
type Person struct {
    Name string
    Age  int
}

func (p Person) String() string {
    return fmt.Sprintf("%s is %d years old", p.Name, p.Age)
}

func main() {
    p := Person{Name: "Alice", Age: 30}
    fmt.Println(p)
}

// Maps
func main() {
    m := map[string]int{
        "apple":  5,
        "banana": 3,
    }
    fmt.Printf("Apples: %d\n", m["apple"])
}

// String operations
func main() {
    s := "Hello"
    s += " World!"
    fmt.Println(s)
    fmt.Printf("Length: %d\n", len(s))
}

Caveats

  • Fragments must be valid TinyGo code that compiles
  • TinyGo supports a subset of Go - some Go features may not be available
  • Remember that exported identifiers (functions, types, variables) must start with uppercase
  • Variables declared with := must be used (Go doesn't allow unused variables)
  • The code is compiled fresh each time, so compilation errors will fail execution
  • TinyGo has limited support for some standard library packages
  • Slices are reference types, maps are reference types
  • Zero values: 0 for numbers, "" for strings, nil for pointers/slices/maps/channels
  • Goroutines and channels have limited support in TinyGo compared to full Go

Connections

influenced by

Container Info

image100hellos/tinygo:latest
build scheduleThursday
fragletno