
oat-latte
A component-based TUI framework for Go.
Measure. Render. Ship.
Two-pass layout
Measure then Render. Every component declares its size before paint — no layout thrash, predictable pixel placement every frame.
Composable widgets
Text, Button, EditText, List, CheckBox, ProgressBar, NotificationManager — all themed, all focusable, all composable via VBox/HBox/Grid.
Focus-first design
DFS focus collection, Tab/Shift-Tab cycling, proxy pattern for key interception, and FocusByRef for programmatic jumps.
Five built-in themes
Default (ANSI-16), Dark, Light, Dracula, Nord. Apply once with WithTheme — every widget inherits and can override via Style.Merge.
Modal dialogs
ShowDialog stacks overlays with a full-screen scrim. Dialogs size by fixed cells or percentage of terminal. HideDialog restores focus.
Goroutine-safe redraws
NotifyChannel lets background goroutines trigger repaints without locks. Key handlers run on the main goroutine — no races.
From zero to running in minutes
package main
import (
"log"
oat "github.com/antoniocali/oat-latte"
"github.com/antoniocali/oat-latte/latte"
"github.com/antoniocali/oat-latte/layout"
"github.com/antoniocali/oat-latte/widget"
)
func main() {
input := widget.NewEditText().
WithHint("Name").
WithPlaceholder("Type something…")
btn := widget.NewButton("Say hello", func() {
// handle press
})
body := layout.NewBorder(
layout.NewVBox(input, btn),
).WithTitle("Hello")
app := oat.NewCanvas(
oat.WithTheme(latte.ThemeDark),
oat.WithBody(body),
)
if err := app.Run(); err != nil {
log.Fatal(err)
}
}