ANSI escape codes in Go
Go's `fmt.Print*` family is byte-clean — `\x1b[31m` just works on Unix and on Windows 10+ (when `ENABLE_VIRTUAL_TERMINAL_PROCESSING` is set, which `golang.org/x/sys/windows` can flip on). For anything more than a handful of escapes, reach for `fatih/color` or, for full TUIs, the Charmbracelet stack (`lipgloss` + `bubbletea`).
Recommended libraries
- github.com/fatih/color
Idiomatic colour helper: `color.New(color.FgRed, color.Bold).Println("oops")`. Auto-detects terminal capability and respects `NO_COLOR`.
- github.com/charmbracelet/lipgloss
CSS-like styling DSL for terminal output (margin, padding, borders, joining). Built on `termenv`; renders to plain ANSI bytes.
- github.com/charmbracelet/bubbletea
Elm-architecture TUI framework — model / update / view. Pairs with lipgloss for styling and bubbles for ready-made widgets.
- github.com/muesli/termenv
Lower-level capability detection — terminal background colour, profile (TrueColor / ANSI 256 / ANSI 16), screen alt-buffer, mouse, bracketed paste.
Idiomatic patterns
package main
import "fmt"
func main() {
fmt.Println("\x1b[1;31merror:\x1b[0m permission denied")
}package main
import "github.com/fatih/color"
func main() {
red := color.New(color.FgRed, color.Bold)
red.Println("error: permission denied")
}package main
import (
"fmt"
"time"
)
func main() {
fmt.Print("\x1b[?1049h") // enter alt screen
defer fmt.Print("\x1b[?1049l") // leave on return
fmt.Print("painted in alt buffer")
time.Sleep(2 * time.Second)
}package main
import "fmt"
func main() {
// \x1b[38;2;R;G;Bm — SGR 38;2 = direct RGB foreground
fmt.Printf("\x1b[38;2;%d;%d;%dm%s\x1b[0m\n", 0xcb, 0xa6, 0xf7, "lavender")
}