What TUI Libraries Does gh-stack Use? Bubble Tea, Bubbles, and Lip Gloss Explained
gh-stack builds its interactive command-line interface using three TUI libraries from the Charm Bracelet ecosystem: Bubble Tea as the core framework, Bubbles for pre-built components, and Lip Gloss for terminal styling.
The gh-stack extension enhances the GitHub CLI with rich terminal interfaces for managing stacked pull requests. According to the source code in github/gh-stack, the project implements its text-based user interface (TUI) by orchestrating these three complementary Go libraries to handle event loops, reusable widgets, and visual styling.
Core Framework: Bubble Tea
At the heart of gh-stack's interactive commands lies Bubble Tea (github.com/charmbracelet/bubbletea), an event-driven framework for building terminal user interfaces. The library implements the Model-View-Update (MVU) architecture, where each command initializes a Bubble Tea program that handles keyboard input, renders views, and manages state transitions.
The submit, modify, and view commands all launch Bubble Tea programs directly:
- In
cmd/submit.go, the command initializes a Bubble Tea model to drive the interactive PR submission flow. - In
cmd/modify.go, the framework handles real-time updates as users modify stack configurations. - In
cmd/view.go, shared view utilities provide generic Bubble Tea rendering logic used across multiple commands.
The foundation follows the standard Bubble Tea pattern requiring three interface implementations:
package main
import (
"github.com/charmbracelet/bubbletea"
)
type model struct{}
func (m model) Init() tea.Cmd { return nil }
func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
switch msg.(type) {
case tea.KeyMsg:
return m, tea.Quit
}
return m, nil
}
func (m model) View() string { return "Press any key to exit…" }
func main() {
p := tea.NewProgram(model{})
if err := p.Start(); err != nil {
panic(err)
}
}
Component Library: Bubbles
While Bubble Tea provides the framework, Bubbles (github.com/charmbracelet/bubbles) supplies reusable UI components that gh-stack imports for specific interactions. The repository utilizes five distinct bubble types across its view implementations in the internal/tui/ directory.
Key Bindings with the key Bubble
The key bubble standardizes keyboard shortcuts across views. internal/tui/submitview/model.go defines shortcuts for submitting or aborting operations, while internal/tui/stackview/model.go uses it for navigation controls and command discovery.
Multi-Line Editing with textarea
For PR descriptions and multi-line input, the textarea bubble provides advanced text editing capabilities. The submit view implements this in internal/tui/submitview/editor.go to capture detailed pull request bodies:
import (
"github.com/charmbracelet/bubbles/textarea"
)
ta := textarea.New()
ta.Placeholder = "Enter your PR description..."
ta.SetWidth(80)
ta.SetHeight(10)
Single-Line Input with textinput
The textinput bubble handles concise, single-line data entry. internal/tui/modifyview/model.go employs this component for fields requiring brief user input, such as branch names or metadata editing.
User Experience Enhancements: help and spinner
The help bubble generates contextual keybinding displays in internal/tui/stackview/model.go, ensuring users understand available commands without leaving the interface. Meanwhile, internal/tui/mergeview/model.go imports the spinner bubble to indicate progress during lengthy operations like merging stacked pull requests.
Styling Engine: Lip Gloss
Lip Gloss (github.com/charmbracelet/lipgloss) completes the stack as a style-definition library for terminal applications. Unlike traditional CSS, Lip Gloss uses Go method chaining to define colors, borders, padding, and typography that render consistently across terminal emulators.
The repository centralizes its aesthetic definitions in two primary locations:
internal/tui/submitview/styles.gocontains view-specific styling rules for the submit interface.internal/theme/theme.godefines the global color palette and shared helpers used consistently across all TUI views.
A typical styling definition matches patterns found in the submit view:
import "github.com/charmbracelet/lipgloss"
var buttonStyle = lipgloss.NewStyle().
Foreground(lipgloss.Color("#FFFFFF")).
Background(lipgloss.Color("#0066FF")).
Padding(0, 2).
Bold(true)
func renderButton(label string) string {
return buttonStyle.Render(label)
}
How the Libraries Integrate
These three TUI libraries operate in concert within gh-stack's architecture. Bubble Tea orchestrates the main event loops in command entry points like cmd/submit.go. During execution, the program instantiates models from internal/tui/ subpackages, which embed Bubbles components for specific interactions. Every rendered element passes through Lip Gloss styles defined in internal/theme/theme.go or view-specific styles files, ensuring consistent visual presentation while handling keyboard input and mouse events.
Summary
- Bubble Tea provides the foundational MVU framework driving all interactive commands in
cmd/submit.go,cmd/modify.go, andcmd/view.go. - Bubbles supplies specialized components including
textareafor editing,textinputfor short fields,keyfor shortcuts,helpfor overlays, andspinnerfor progress indicators across view models. - Lip Gloss handles all terminal styling through centralized definitions in
internal/theme/theme.goand view-specific files likeinternal/tui/submitview/styles.go. - Together, these Charm Bracelet libraries enable gh-stack to render responsive tables, forms, and colored text interfaces without leaving the terminal.
Frequently Asked Questions
Does gh-stack use any TUI libraries besides Bubble Tea, Bubbles, and Lip Gloss?
No. According to the source analysis of github/gh-stack, the project relies exclusively on the Charm Bracelet trilogy. While standard Go libraries handle Git operations and GitHub API interactions, all terminal interface rendering derives from these three specific libraries.
Which gh-stack command uses the most Bubbles components?
The submit command implements the richest component set. It utilizes textarea for description editing (in internal/tui/submitview/editor.go), key for binding management, and draws on styling from the submit view, making it the most component-dense interface in the application.
How does gh-stack handle styling consistency across different views?
The project maintains visual coherence through internal/theme/theme.go, which exports shared Lip Gloss styles and color constants. Individual views like those in internal/tui/submitview/styles.go extend these base definitions, ensuring that borders, padding, and colors remain uniform while allowing view-specific customizations.
Can I use these same TUI libraries to build my own CLI tools?
Yes. Bubble Tea, Bubbles, and Lip Gloss are open-source Go libraries designed for general use. The gh-stack implementation demonstrates production patterns: initialize a Bubble Tea program in your command entry point, import specific Bubbles for complex inputs, and apply Lip Gloss styles for professional terminal presentation.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →