
Bubble Tea
A Go framework from Charm for terminal apps built on the Elm Architecture: one model holds the state, Update turns messages into a new model, and View describes the screen.
- What it is
- Terminal user interfaces (TUIs)
- Type
- Open source
- Made by
- Charmbracelet, Inc.
- License
- MIT
- Facts checked
- 13 October 2026
What it is
A Bubble Tea program is a model plus three methods. Init returns an optional first command. Update receives a message (a key press, a mouse click, a window resize, a timer tick, a server response), returns the updated model and optionally a command. View turns the model into a tea.View, and the runtime redraws after every update, so the app has no redrawing logic of its own. Commands (tea.Cmd) are functions that do I/O; the runtime runs each one in its own goroutine and feeds the message it returns back into Update. tea.Batch runs several at once with no ordering guarantees, tea.Sequence one after another.
Version 2, released in February 2026, made the view declarative: instead of commands such as tea.EnterAltScreen, View sets fields like AltScreen, MouseMode and the window title, and the runtime applies them. Its “Cursed Renderer”, modeled on the ncurses rendering algorithm, redraws at most 60 times a second by default (configurable up to 120); Charm says it cuts bandwidth by orders of magnitude for apps served over SSH with its Wish library. It reads the Kitty keyboard protocol where the terminal supports it, so apps can bind keys like shift+enter and see key releases, and it downsamples colors to what the terminal can show. Apps can run full-window in the alternate screen or inline below the prompt.
Bubble Tea is the interaction layer of a set of Charm libraries: Bubbles provides components such as text inputs, viewports and spinners, and Lip Gloss handles styling and layout. Charmbracelet, Inc. is an active, venture-funded company: it shipped v2.1.0 in October 2026 and builds its own AI coding agent, Crush, on these libraries.
Why teams pick it
- One model and one Update function make state changes predictable and easy to test: every change comes from a message
- Concurrency without shared state: commands run in goroutines and report back as messages, so I/O never blocks the UI
- A family of libraries (Bubbles components, Lip Gloss styling, Wish for SSH apps) and, per its README, more than 18,000 applications built on it, including tools from AWS, NVIDIA and Microsoft Azure
- v2 handles modern terminal features for you: keyboard enhancements, color downsampling, synchronized rendering and clipboard transfer over SSH
Watch out for
- v2 broke the API: the import path moved to
charm.land/bubbletea/v2,Viewreturns atea.Viewinstead of a string, and key and mouse messages were split into new types, so v1 code needs the upgrade guide - The app owns stdin and stdout, so you can’t print-debug: logs go to a file (
tea.LogToFile) and Delve must run in headless mode - Commands started with
tea.Batchrun concurrently with no ordering guarantees, so their messages can arrive in any order; usetea.Sequencewhen order matters - Richer key handling only works in terminals that support progressive keyboard enhancement (Ghostty, Kitty, WezTerm, iTerm2 and others); apps need fallbacks elsewhere
Alternatives
What all terminal user interfaces (tuis) have in common →Compare side by side →How it fits with other technologies
What Bubble Tea uses
A countdown that ticks with a command (Bubble Tea v2) · go
package main
import (
"fmt"
"os"
"time"
tea "charm.land/bubbletea/v2"
)
type tickMsg time.Time
// A command: the runtime runs it in a goroutine and sends its result to Update.
func tick() tea.Cmd {
return tea.Tick(time.Second, func(t time.Time) tea.Msg { return tickMsg(t) })
}
type model struct{ left int }
func (m model) Init() tea.Cmd { return tick() }
func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
switch msg := msg.(type) {
case tea.KeyPressMsg:
if msg.String() == "q" || msg.String() == "ctrl+c" {
return m, tea.Quit
}
case tickMsg:
m.left--
if m.left == 0 {
return m, tea.Quit
}
return m, tick()
}
return m, nil
}
func (m model) View() tea.View {
return tea.NewView(fmt.Sprintf("Quitting in %d seconds. Press q to quit now.\n", m.left))
}
func main() {
if _, err := tea.NewProgram(model{left: 5}).Run(); err != nil {
fmt.Println("error:", err)
os.Exit(1)
}
}See it in a real stack
No architecture uses Bubble Tea yet. Drop it into the playground and wire it up yourself.Open playground →Worth exploring
Where it came from2019–2026
Charm started in 2019 as a group of friends from consumer tech (Apple, Last.fm, TweetDeck) who wanted to bring modern product design to the command line. Their first projects, Glow and Glamour, styled Markdown in the terminal, but they also needed a way to build interactive interfaces. Christian Rocha, who came from Haskell and Elm, wanted to write stateful text interfaces without thinking about rendering, and found nothing in the Go ecosystem that did it, so the team built Bubble Tea on the Elm Architecture. Its first tagged release, v0.1.0, came out in April 2020.
Bubble Tea grew with its sister libraries, Bubbles and Lip Gloss, and with Charm’s own tools built on them, such as Glow. By November 2023, when Charm raised $6 million in a round led by Gradient, Google’s AI-focused fund, it powered more than 4,000 apps. Charm tagged v1.0.0 in August 2024 as an “honorary release” to mark the API as stable.
When AI coding agents moved into the terminal, Charm decided the libraries had to carry more weight. Bubble Tea v2, released with Lip Gloss and Bubbles v2 on 23 February 2026, brought the new Cursed Renderer, richer keyboard input and a declarative view; the v2 branches had run Charm’s coding agent Crush in production for months first. Charm says it had never pushed a breaking change before v2.
Why it’s built this way
- The Elm Architecture in Go
- A single model updated only by messages lets developers build stateful, animated interfaces without managing redraws, the experience Charm’s founders knew from building browser UIs in Elm.
- Commands instead of user-managed goroutines
- All I/O goes through
tea.Cmdfunctions that the runtime runs concurrently and turns into messages, so many asynchronous operations stay simple and the model is only touched inUpdate. - Inline mode as a first-class use case, compiled to native code
- Charm wanted interfaces that can appear inline in a normal terminal session, not only full-screen apps, and sees speed as one of the terminal’s main advantages, locally and over SSH.
- A declarative view and one owner of terminal I/O in v2
- In v1, Bubble Tea and Lip Gloss could fight over the terminal (one reading keys, the other querying the background color), and terminal modes were toggled with commands. In v2 Bubble Tea owns all I/O and the view simply declares what it wants.
Timeline
- 2019
Charm founded to build tools for the command line
- 2020
Bubble Tea v0.1.0 tagged (April)
- 2023
Charm raises $6M led by Gradient; Bubble Tea powers over 4,000 apps (November)
- 2024
v1.0.0 marks the API as stable (August)
- 2026
v2.0.0 with the Cursed Renderer and the charm.land import path (February)
- 2026
v2.1.0 adds the OSC 7501 program status protocol (October)
- Charm blog: The Next Generation of the Command Line ($6MM led by Gradient, Nov 2023)
- Charm blog: The Charm guide to building popular open source software (why Bubble Tea was built)
- Go module proxy: bubbletea v0.1.0 (published April 2020)
- Bubble Tea release notes: v1.0.0 (Aug 2024)
- Charm blog: v2, the next generations of Bubble Tea, Lip Gloss and Bubbles (Feb 2026)
- Bubble Tea release notes: v2.0.0 (Feb 2026)
- Bubble Tea release notes: v2.1.0, OSC 7501 (Oct 2026)
Sources7 · facts checked 13 October 2026
- Bubble Tea README (model, Init, Update, View; debugging; Bubbles and Lip Gloss; 18,000 applications)
- Bubble Tea tutorial: Commands (Cmds run in a goroutine and return a Msg)
- Bubble Tea v2 API docs (Cmd, Batch, Sequence, Tick, WithFPS, View)
- Bubble Tea release notes: v2.0.0 (Cursed Renderer, declarative View, keyboard enhancements, color downsampling)
- Charm blog: v2 (inline mode, synchronized rendering, clipboard over SSH, Crush, 25,000 apps)
- Bubble Tea release notes: v2.1.0 (Oct 2026)
- Bubble Tea LICENSE (MIT, Charmbracelet, Inc.)