Open-Source Wikis

/

Bubble Tea

/

Features

/

Alt screen and inline output

charmbracelet/bubbletea

Alt screen and inline output

Active contributors: aymanbagabas, meowgorithm

Purpose

Bubble Tea programs can run in two modes: inline (printing into the user's normal scrollback) or alt screen (taking over the screen until the program exits). The two modes share the same renderer but differ in how output is scoped and what auxiliary primitives (Println, ClearScreen) do.

Choosing a mode

// Alt screen
func (m model) View() tea.View {
    v := tea.NewView("Hello")
    v.AltScreen = true
    return v
}

// Inline (default)
func (m model) View() tea.View {
    return tea.NewView("Hello")
}

The alt screen is the same buffer that vim, less, and tmux use. The renderer issues CSI ? 1049 h to enter and CSI ? 1049 l to leave. On exit, the original screen content reappears as if the program had never run.

Toggling at runtime

Toggle the alt screen by changing the View.AltScreen field across renders. The renderer detects the transition (shouldUpdateAltScreen in cursed_renderer.go) and emits the appropriate sequence on the next flush.

case tea.KeyPressMsg:
    if msg.String() == "f" {
        m.fullscreen = !m.fullscreen
    }

func (m model) View() tea.View {
    v := tea.NewView(m.body())
    v.AltScreen = m.fullscreen
    return v
}

examples/altscreen-toggle/ demonstrates this pattern.

Println and Printf

In inline mode, tea.Println and tea.Printf insert a line above the rendered region. The renderer scrolls its output up and writes the line in the freshly-revealed area. This is the mechanism behind the package-manager and progress-download demos that print one line per completed item while a spinner stays at the bottom.

case downloadCompleteMsg:
    return m, tea.Printf("✓ downloaded %s", msg.name)

In alt screen mode, Println/Printf are no-ops — there is no scrollback to insert above.

ClearScreen

tea.ClearScreen is a Cmd that emits clearScreenMsg. The runtime forwards it to renderer.clearScreen, which writes CSI 2 J and moves the cursor to the home position. Useful for occasional manual clears in inline mode; never necessary for normal redraws (the renderer handles those automatically).

Window title

In any mode, View.WindowTitle sets the title via OSC 0 / 2. The renderer remembers the last value so it can clear the title on shutdown:

v := tea.NewView("...")
v.WindowTitle = "Grocery List"

Progress bar

The OSC 9 ; 4 progress bar is supported by Windows Terminal, ghostty, and a few others. Set View.ProgressBar to a non-nil *ProgressBar:

v := tea.NewView("Downloading...")
v.ProgressBar = tea.NewProgressBar(tea.ProgressBarDefault, 42)

ProgressBarState values: ProgressBarNone, ProgressBarDefault, ProgressBarError, ProgressBarIndeterminate, ProgressBarWarning. The renderer resets the bar to None when the program closes.

Keyboard caveats

When the alt screen toggles, the Kitty keyboard protocol treats main and alt screens as separate registries. The renderer therefore re-issues the keyboard enhancement sequence for each screen so behavior stays consistent (cursed_renderer.go close/start logic).

Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.

Alt screen and inline output – Bubble Tea wiki | Factory