LiveCodes supports Go (Golang) execution in the browser using Yaegi (interpreter) and TinyGo (WebAssembly compiler).
Configuration
Language Name: go (Yaegi) or go-wasm (TinyGo)
File Extensions: .go, .golang
Editor: Script editor
Compiler: Yaegi interpreter or TinyGo WASM
Formatter: gofmt
Go with Yaegi
Yaegi is a Go interpreter that runs Go code in the browser:
package main
import (
"fmt"
"strings"
)
func main() {
// Basic output
fmt.Println("Hello, World!")
// Variables
name := "Alice"
age := 30
fmt.Printf("Name: %s, Age: %d\n", name, age)
// String manipulation
upper := strings.ToUpper(name)
fmt.Println(upper)
// Arrays and slices
numbers := []int{1, 2, 3, 4, 5}
for i, n := range numbers {
fmt.Printf("Index %d: %d\n", i, n)
}
}
Functions
package main
import "fmt"
// Regular function
func greet(name string) string {
return "Hello, " + name + "!"
}
// Multiple return values
func divide(a, b float64) (float64, error) {
if b == 0 {
return 0, fmt.Errorf("division by zero")
}
return a / b, nil
}
// Variadic function
func sum(numbers ...int) int {
total := 0
for _, n := range numbers {
total += n
}
return total
}
func main() {
fmt.Println(greet("Alice"))
result, err := divide(10, 2)
if err != nil {
fmt.Println("Error:", err)
} else {
fmt.Printf("Result: %.2f\n", result)
}
fmt.Println("Sum:", sum(1, 2, 3, 4, 5))
}
Structs and Methods
package main
import "fmt"
type Person struct {
Name string
Age int
Email string
}
// Method on Person
func (p Person) Greet() string {
return fmt.Sprintf("Hello, I'm %s", p.Name)
}
// Pointer receiver method
func (p *Person) HaveBirthday() {
p.Age++
}
func main() {
person := Person{
Name: "John Doe",
Age: 30,
Email: "john@example.com",
}
fmt.Println(person.Greet())
person.HaveBirthday()
fmt.Printf("New age: %d\n", person.Age)
}
Interfaces
package main
import "fmt"
type Shape interface {
Area() float64
Perimeter() float64
}
type Rectangle struct {
Width float64
Height float64
}
func (r Rectangle) Area() float64 {
return r.Width * r.Height
}
func (r Rectangle) Perimeter() float64 {
return 2 * (r.Width + r.Height)
}
type Circle struct {
Radius float64
}
func (c Circle) Area() float64 {
return 3.14159 * c.Radius * c.Radius
}
func (c Circle) Perimeter() float64 {
return 2 * 3.14159 * c.Radius
}
func printShapeInfo(s Shape) {
fmt.Printf("Area: %.2f, Perimeter: %.2f\n", s.Area(), s.Perimeter())
}
func main() {
rect := Rectangle{Width: 10, Height: 5}
circ := Circle{Radius: 7}
printShapeInfo(rect)
printShapeInfo(circ)
}
Goroutines and Channels
package main
import (
"fmt"
"time"
)
func worker(id int, jobs <-chan int, results chan<- int) {
for j := range jobs {
fmt.Printf("Worker %d processing job %d\n", id, j)
time.Sleep(time.Second)
results <- j * 2
}
}
func main() {
jobs := make(chan int, 5)
results := make(chan int, 5)
// Start workers
for w := 1; w <= 3; w++ {
go worker(w, jobs, results)
}
// Send jobs
for j := 1; j <= 5; j++ {
jobs <- j
}
close(jobs)
// Collect results
for a := 1; a <= 5; a++ {
<-results
}
}
Error Handling
package main
import (
"errors"
"fmt"
)
func validateAge(age int) error {
if age < 0 {
return errors.New("age cannot be negative")
}
if age > 150 {
return errors.New("age too high")
}
return nil
}
func processUser(name string, age int) error {
if name == "" {
return fmt.Errorf("name cannot be empty")
}
if err := validateAge(age); err != nil {
return fmt.Errorf("invalid age: %w", err)
}
fmt.Printf("Processing user: %s, %d\n", name, age)
return nil
}
func main() {
if err := processUser("Alice", 30); err != nil {
fmt.Println("Error:", err)
}
if err := processUser("", 25); err != nil {
fmt.Println("Error:", err)
}
}
DOM Manipulation
Access browser APIs through JavaScript interop:
package main
import (
"syscall/js"
)
func main() {
// Get document
doc := js.Global().Get("document")
// Create element
div := doc.Call("createElement", "div")
div.Set("textContent", "Hello from Go!")
div.Get("classList").Call("add", "container")
// Append to body
body := doc.Get("body")
body.Call("appendChild", div)
// Create button
button := doc.Call("createElement", "button")
button.Set("textContent", "Click me")
// Add event listener
callback := js.FuncOf(func(this js.Value, args []js.Value) interface{} {
js.Global().Call("alert", "Button clicked!")
return nil
})
button.Call("addEventListener", "click", callback)
body.Call("appendChild", button)
}
Automatic formatting with gofmt:
// Before formatting
package main
import "fmt"
func main(){fmt.Println("Hello")}
// After formatting (Ctrl+Shift+F)
package main
import "fmt"
func main() {
fmt.Println("Hello")
}
Example Projects
Counter
package main
import (
"fmt"
"syscall/js"
)
var count = 0
func createCounter() {
doc := js.Global().Get("document")
body := doc.Get("body")
// Display
display := doc.Call("createElement", "div")
display.Set("id", "display")
display.Set("textContent", fmt.Sprintf("Count: %d", count))
body.Call("appendChild", display)
// Increment button
incBtn := doc.Call("createElement", "button")
incBtn.Set("textContent", "Increment")
incBtn.Call("addEventListener", "click", js.FuncOf(func(this js.Value, args []js.Value) interface{} {
count++
doc.Call("getElementById", "display").Set("textContent", fmt.Sprintf("Count: %d", count))
return nil
}))
body.Call("appendChild", incBtn)
// Decrement button
decBtn := doc.Call("createElement", "button")
decBtn.Set("textContent", "Decrement")
decBtn.Call("addEventListener", "click", js.FuncOf(func(this js.Value, args []js.Value) interface{} {
count--
doc.Call("getElementById", "display").Set("textContent", fmt.Sprintf("Count: %d", count))
return nil
}))
body.Call("appendChild", decBtn)
}
func main() {
createCounter()
}
Data Structures
package main
import "fmt"
type Stack struct {
items []int
}
func (s *Stack) Push(item int) {
s.items = append(s.items, item)
}
func (s *Stack) Pop() (int, bool) {
if len(s.items) == 0 {
return 0, false
}
index := len(s.items) - 1
item := s.items[index]
s.items = s.items[:index]
return item, true
}
func (s *Stack) Peek() (int, bool) {
if len(s.items) == 0 {
return 0, false
}
return s.items[len(s.items)-1], true
}
func main() {
stack := &Stack{}
stack.Push(1)
stack.Push(2)
stack.Push(3)
if top, ok := stack.Peek(); ok {
fmt.Printf("Top: %d\n", top)
}
for {
if item, ok := stack.Pop(); ok {
fmt.Printf("Popped: %d\n", item)
} else {
break
}
}
}
Go WebAssembly (TinyGo)
For full WebAssembly compilation, use go-wasm:
package main
import (
"syscall/js"
)
func fibonacci(n int) int {
if n <= 1 {
return n
}
return fibonacci(n-1) + fibonacci(n-2)
}
func main() {
// Export function to JavaScript
js.Global().Set("fibonacci", js.FuncOf(func(this js.Value, args []js.Value) interface{} {
n := args[0].Int()
return fibonacci(n)
}))
// Keep program running
select {}
}
TinyGo WebAssembly produces smaller binaries optimized for the browser but with some standard library limitations.
Supported Packages
Yaegi supports many standard library packages:
fmt - Formatted I/O
strings - String manipulation
math - Mathematical functions
time - Time and duration
errors - Error handling
sort - Sorting algorithms
encoding/json - JSON encoding/decoding
package main
import (
"encoding/json"
"fmt"
"time"
)
type User struct {
Name string `json:"name"`
Email string `json:"email"`
CreatedAt time.Time `json:"created_at"`
}
func main() {
user := User{
Name: "Alice",
Email: "alice@example.com",
CreatedAt: time.Now(),
}
data, _ := json.MarshalIndent(user, "", " ")
fmt.Println(string(data))
}
Best Practices
Always handle errors explicitly:result, err := someFunction()
if err != nil {
fmt.Println("Error:", err)
return
}
// Use result
Use Pointers for Large Structs
Pass large structs by pointer:// Good
func processUser(u *User) {
// modify user
}
// Inefficient for large structs
func processUser(u User) {
// creates copy
}
Use defer for resource cleanup:func processFile() error {
f, err := os.Open("file.txt")
if err != nil {
return err
}
defer f.Close()
// process file
return nil
}
Limitations
Limited Packages: Yaegi supports a subset of the Go standard library. Some packages may not be available.
No CGo: C interop is not supported in browser environments.
For full standard library support, consider using go-wasm with TinyGo, though it has different trade-offs.
Python
Alternative dynamic language
Rust
Systems programming language
WebAssembly
WASM compilation target
TypeScript
Typed JavaScript alternative