charmbracelet /bubbletea
A powerful little TUI framework 🏗
★ 45,662⑂ 1,832👁 143⑃ 1,121● 474▤ 83◈ 244
45,662
stars
+9
1,832
forks
143
watchers
1,121
prs
474
issues
83
releases
244
discussions
README
Bubble Tea
The fun, functional and stateful way to build terminal apps. A Go framework
based on [The Elm Architecture][elm]. Bubble Tea is well-suited for simple and
complex terminal applications, either inline, full-window, or a mix of both.
Bubble Tea is in use in production and includes a number of features and
performance optimizations we’ve added along the way. Among those is
a high-performance cell-based renderer, built-in color downsampling,
declarative views, high-fidelity keyboard and mouse handling, native clipboard
support, and more.
To get started, see the tutorial below, the [examples][examples], the
[docs][docs], and some common resources.
[!TIP]
Upgrading from v1? Check out the upgrade guide, or
point your LLM at it and let it go to town.
By the way
Be sure to check out [Bubbles][bubbles], a library of common UI components for Bubble Tea.
---
Tutorial
Bubble Tea is based on the functional design paradigms of [The Elm
Architecture][elm], which happens to work nicely with Go. It's a delightful way
to build applications.
This tutorial assumes you have a working knowledge of Go.
By the way, the non-annotated source code for this program is available
[on GitHub][tut-source].
[elm]: https://guide.elm-lang.org/architecture/
[tut-source]: https://github.com/charmbracelet/bubbletea/tree/main/tutorials/basics
Enough! Let's get to it.
For this tutorial, we're making a shopping list.
To start we'll define our package and import some libraries. Our only external
import will be the Bubble Tea library, which we'll call tea for short.
go
package main
// These imports will be used later in the tutorial. If you save the file
// now, Go might complain they are unused, but that's fine.
// You may also need to run go mod tidy to download bubbletea and its
// dependencies.
import (
"fmt"
"os"
tea "charm.land/bubbletea/v2"
)
Bubble Tea programs are comprised of a model that describes the application
state and three simple methods on that model:
- Init, a function that returns an initial command for the application to run.
- Update, a function that handles incoming events and updates the model accordingly.
- View, a function that renders the UI based on the data in the model.
The Model
So let's start by defining our model which will store our application's state.
It can be any type, but a struct usually makes the most sense.
go
type model struct {
choices []string // items on the to-do list
cursor int // which to-do list item our cursor is pointing at
selected map[int]struct{} // which to-do items are selected
}
Initialization
Next, we’ll define our application’s initial state. Init can return a Cmd
that could perform some initial I/O. For now, we don’t need to do any I/O, so
for the command, we’ll just return nil, which translates to “no command.”
go
func initialModel() model {
return model{
// Our to-do liTop issues
#1590If tea program quits too early, garbage chars are printed17 comments · 2026-02-18#163Displaying images17 comments · 2021-11-29#1698Tinygo support14 comments · 2026-05-11#573Altscreen: rendering artifacts when resizing window13 comments · 2022-10-24#1225lipgloss styles rendered incorrectly when `.Width()` applied12 comments · 2024-11-06#1017The visible area in viewport may seem incorrect when content exceed the viewport.Width10 comments · 2024-05-13#309Compositing10 comments · 2022-05-08#616bug: loss of input on ReleaseTerminal / Bubbletea shutdown9 comments · 2022-11-30
Discussions
#1862Cursor style ownership across terminal handoffs0 comments · 2026-10-12#1825TrafTest: A lightweight local traffic simulator & load sandbox with Bubble Tea TUI and Web UI0 comments · 2026-09-30#1775Bermuda — a scheduler board in Bubble Tea, and two things it taught me about long-lived TUIs0 comments · 2026-08-20#1768revision: A lazygit-style TUI for SVN0 comments · 2026-08-14#1760v2 scrolling performance and pending fixes0 comments · 2026-08-08#1747Compositor clips layers positioned away from the origin when no root layer spans the viewport0 comments · 2026-07-29#1732VibeWorld: a shared world that runs in your terminal2 comments · 2026-07-12#1715An LLM writes a Bubble Tea app - go build decides whether it counts (teatest next?)1 comments · 2026-06-12
Latest release
v2.1.1 v2.1.1 2026-10-28Terminal size query vulnerability This patch version fixes a vulnerability reported by @Reload3d. You can find the details of the exploit here. Best regards, Charm XX 💫 Changelog Fixed 9c6c325f83348ee7215fb7a7aca3bc6316217056: fix: ingnore implausible terminal resize reports (1887) (@andrinoff) Other stuff 67b4c7a8a2b34a0b1ce15261b0c705bc7e1a04b7: v2.1.1 (@andrinoff) --- Thoughts? Questions? We love hearing from you. Feel free to reach out on X, Discord, Slack, The Fediverse, Bluesky.