Bubble Tea
A Go framework based on The Elm Architecture for building terminal UIs, from simple prompts to full-window, high-performance TUI applications.
Repository Health
Technical Analysis
Bubble Tea is a framework from Charm for building terminal user interfaces in Go. It applies The Elm Architecture — a single Model holding application state, an Update function that reacts to incoming messages, and a View function that renders the UI — giving terminal apps the same predictable, unidirectional data flow popularized by Elm and Redux.
The framework ships a high-performance, cell-based renderer with built-in color downsampling, declarative view composition through layered View values, and high-fidelity keyboard, mouse, and paste handling, alongside native clipboard support. Programs can run inline, in full-window alt-screen mode, or mix both, and Bubble Tea handles terminal setup, raw-mode input, and redraw scheduling so application code only has to describe state transitions and rendering.
Bubble Tea is battle-tested in production and anchors the wider Charm ecosystem: Bubbles supplies ready-made components (text inputs, viewports, spinners), Lip Gloss handles styling and layout, and Harmonica adds spring-based animation. Thousands of published tools — from dotfile managers to Hacker News readers to Tetris clones — are built on top of it.
What You Get
- A
Modelinterface (Init,Update,View) that structures any TUI as a pure state machine - A cell-based renderer with automatic ANSI color downsampling for the terminal’s actual color profile
- High-fidelity keyboard, mouse, and bracketed-paste event handling via
KeyPressMsg,MouseMsg, and paste messages - Native OS clipboard read/write support without shelling out to external tools
- Composable
Viewlayers, including per-view mouse handlers and cursor, window-title, and progress-bar control ProgramOptionfunctions (WithContext,WithInput,WithOutput,WithEnvironment) for embedding Bubble Tea in remote sessions like SSH
Common Use Cases
- Building full-window TUI dashboards and admin tools that run over SSH or locally
- Writing interactive CLI wizards and forms (multi-step prompts, selection lists, text inputs)
- Creating developer tools like
chezmoiandgh-dashthat need a rich, stateful terminal UI - Building terminal games and visualizations (Tetris clones, cellular automata, ASCII animations)
- Adding an inline, non-full-screen interactive component to an otherwise scripted CLI
Under The Hood
Architecture
Bubble Tea’s public API centers on tea.go, which defines the Model interface (Init/Update/View) and the Program type that drives the event loop. commands.go and key.go/mouse.go layer typed message handling on top, while options.go exposes a functional-options constructor (WithContext, WithInput, WithOutput, WithEnvironment) so NewProgram’s signature stays stable as capabilities grow. Beneath this public layer sits a platform-abstraction layer split by build tags — tty_unix.go/tty_windows.go, termios_bsd.go/termios_unix.go/termios_windows.go/termios_other.go, and signals_unix.go/signals_windows.go — isolating raw-mode terminal setup and signal handling per OS. Core event and rendering primitives (Msg is a direct type alias for uv.Event) are delegated to the sibling charmbracelet/ultraviolet module rather than reimplemented, and renderer.go/cursed_renderer.go build the cell-based diffing renderer on top of that. The Model interface is the single contract every downstream consumer (Bubbles components, the wider Charm ecosystem, and thousands of dependent applications) is built against, so it is the one abstraction that cannot change without a major version bump — which the repo has in fact done for v2.
Tech Stack
The module (charm.land/bubbletea/v2, Go 1.25) depends on charmbracelet/colorprofile for terminal color-profile detection, charmbracelet/ultraviolet for core terminal event/rendering primitives, charmbracelet/x/ansi and charmbracelet/x/term for low-level ANSI/terminal handling, lucasb-eyer/go-colorful for color math, and muesli/cancelreader for cancellable stdin reads. Indirect dependencies include aymanbagabas/go-udiff (render diffing), mattn/go-runewidth and rivo/uniseg (Unicode width/segmentation for correct cell rendering), and charmbracelet/x/termios. The project builds via a Taskfile.yaml (the Task runner) rather than a Makefile, and CI is a set of dedicated GitHub Actions workflows — separate build, lint, coverage, and examples pipelines plus Dependabot and a lint-sync workflow — rather than one monolithic pipeline.
Code Quality
Seven _test.go files cover the core (tea_test.go, 18 test functions exercising panic recovery, goroutine behavior, and context cancellation), plus dedicated tests for commands, the cursed renderer, exec, options, screen, and logging. Concurrency-sensitive test state uses sync/atomic rather than ad hoc locking. Errors are surfaced as explicit sentinel values (ErrProgramPanic, ErrProgramKilled, ErrInterrupted) instead of leaking raw panics to callers. Cross-platform correctness is enforced structurally through Go build-tag file splits (unix vs. windows vs. bsd variants of tty, termios, and signal handling) rather than runtime branching, and a standalone lint CI workflow with a lint-sync companion suggests linting is treated as a first-class, kept-in-sync concern.
API Design
The public surface is deliberately minimal: implement three methods on a model type and call tea.NewProgram(model).Run(). Message handling follows Go’s idiomatic type-switch pattern over an interface (Msg), and program configuration uses the functional-options pattern (ProgramOption) so new capabilities (context, custom I/O, environment injection for SSH sessions) can be added without breaking existing call sites. Exported types carry extensive godoc comments with runnable example snippets inline, and a tutorials/ directory plus 30+ programs under examples/ (from a minimal counter to canvas rendering and file pickers) give newcomers a graduated on-ramp. The main real cost for a new user is conceptual, not mechanical: adopting the Elm-style unidirectional message loop is a genuine departure from Go’s typical imperative style, even though the three-method contract itself is small.
Used by 13 apps in this directory
Plandex
AI Code Assistants
An open-source, terminal-based AI coding agent built for large tasks and real codebases — with its own version control for plans, a 2M-token effective context window, and self-hosted or cloud deployment.
PostHog
Ab Testing Experimentation · Analytics · Developer Tools
The all-in-one open source product platform combining analytics, session replay, feature flags, error tracking, AI observability, and a built-in data warehouse in a single self-hostable stack.
Teleport
Authentication · Security
Zero-trust infrastructure access platform that replaces credentials and VPNs with short-lived certificates, SSO, and identity-aware proxies for SSH, Kubernetes, databases, RDP, and AI agents.
Tusk
AI Code Assistants · Developer Tools · Devops
Record live API traffic and replay it as deterministic, sandboxed tests, plus AI code review and unit test generation, all from one Go CLI built by YC W2024's Use-Tusk.