A small, dependency-light toolkit for building terminal UIs with Bubble Tea / Lip Gloss. It gives you three things:
layout— theFramerender primitive plus structural tools: headers, rules, sections, panels/boxes, sticky footers, a width-clamped scrollable body/viewport, scroll state, responsive height "tiers", and a focusRingfor tab-cycling between panels (Frame,Header,Panel,Section,SplitStickyFooter,ScrollableBody,ScrollState,Tier,Ring,ScreenFrame,TooNarrow, …).panels— data visualization that renders neutral structs /[]float64into aligned, styled charts: bar, line, candlestick (OHLC), pie/proportion, and ledger, plus small formatting widgets (Meter,Toggle,Flash).theme— atheme.Themevalue (palette + copy) withtheme.Default(); install your own withtheme.Useto restyle everything.
viewkit depends only on charmbracelet/lipgloss, charmbracelet/x/ansi, and
the standard library. The package dependency flows panels → layout → theme.
go get github.com/codyconfer/viewkit@latestimport (
"github.com/codyconfer/viewkit/layout"
"github.com/codyconfer/viewkit/panels"
"github.com/codyconfer/viewkit/theme"
)viewkit is deliberately domain-agnostic: data crosses the boundary as neutral
structs (panels.Datum, panels.OHLC, panels.LedgerRow) and formatter
callbacks (func(float64) string) — never your application's domain types. A
layout.Frame carries the render width and focus state; construct one with
layout.NewFrame(width) and pass it to the charts.
frame := layout.NewFrame(80)
// structural layout — methods on the frame
body := frame.Panel("STATUS", frame.Row("tokens", "1.2M"))
// charts — functions that take the frame
chart := panels.Bar(frame, "GPUs", []panels.Datum{
{Label: "gpu", Value: 12},
{Label: "cloud", Value: 30},
}, 40, fmtNum, "no data")The palette and UI copy are injectable. Build a theme.Theme from
theme.Default(), override what you want, and install it once at startup with
theme.Use — every panel and layout helper renders from the active theme
(theme.Cur()):
th := theme.Default()
th.Accent = lipgloss.NewStyle().Foreground(lipgloss.Color("212"))
th.TooNarrowTitle = "SCREEN TOO SMALL"
theme.Use(th)Structural dimensions (theme.BodyWidth, theme.MinScreenWidth, the height
tiers, …) are exported constants — viewkit's layout contract — rather than part
of Theme; set per-view width via layout.NewFrame(width).
Early days — the API may still shift before a v1. It was extracted from the
goose project, which remains its primary
consumer and reference usage.
The module ships its own .golangci.yml. Build, test, vet, and lint with:
go build ./...
go test ./...
go vet ./...
golangci-lint runMIT © Cody Confer