Open-Source Wikis

/

Bubble Tea

/

Bubble Tea

/

Getting started

charmbracelet/bubbletea

Getting started

This page covers prerequisites, how to add Bubble Tea to a project, and how to run the tests, examples, and tutorials in this repository.

Prerequisites

  • Go: 1.25.0 or newer. The module declares go 1.25.0 in go.mod.
  • A real terminal for running examples (Bubble Tea opens the controlling TTY for input). The library still works in pipelines via WithoutRenderer/WithInput(nil).
  • Optional development tools:
    • Task (Taskfile.yaml) for running task lint and task test.
    • golangci-lint v2.9 (matches .github/workflows/lint.yml).
    • gofumpt and goimports — both are configured as formatters in .golangci.yml.
    • delve for debugging headless TUIs (see Debugging).

Adding Bubble Tea to your own project

go get charm.land/bubbletea/v2@latest
import tea "charm.land/bubbletea/v2"

Bubble Tea pulls in github.com/charmbracelet/colorprofile, github.com/charmbracelet/ultraviolet, github.com/charmbracelet/x/ansi, github.com/charmbracelet/x/term, github.com/lucasb-eyer/go-colorful, github.com/muesli/cancelreader, and golang.org/x/sys. See go.mod for the exact versions.

A minimal program

The smallest legal Bubble Tea program implements Init, Update, and View:

package main

import (
    "fmt"
    "os"

    tea "charm.land/bubbletea/v2"
)

type model struct{ count int }

func (m model) Init() tea.Cmd { return nil }

func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
    if k, ok := msg.(tea.KeyPressMsg); ok && k.String() == "q" {
        return m, tea.Quit
    }
    return m, nil
}

func (m model) View() tea.View { return tea.NewView(fmt.Sprintf("Count: %d", m.count)) }

func main() {
    if _, err := tea.NewProgram(model{}).Run(); err != nil {
        fmt.Fprintln(os.Stderr, err)
        os.Exit(1)
    }
}

The full annotated tutorial (the grocery-list app from the README) lives in tutorials/basics/main.go.

Running the tests in this repo

The library uses standard go test:

go test ./...

The Taskfile target wraps the same command:

task test

Race-mode coverage is what CI runs (see .github/workflows/coverage.yml):

go test -race -covermode=atomic -coverprofile=coverage.txt ./...

Some tests (e.g. screen_test.go, tea_test.go) compare against golden files in testdata/. To regenerate after intentional output changes, pass -update to the affected tests if their helpers support it (the project uses github.com/charmbracelet/x/exp/golden).

Running the examples

The examples/ directory is a separate Go module so its dependencies (Bubbles, Lip Gloss, Glamour) do not leak into the main library. To run any example:

cd examples
go run ./simple
go run ./list-fancy
go run ./tabs

See Examples package for the catalog. Each example has a brief description in examples/README.md.

Running the tutorials

Tutorials are also a separate module:

cd tutorials
go run ./basics    # the grocery list from the README
go run ./commands  # the same tutorial extended with HTTP calls

Linting

task lint
# or
golangci-lint run

.golangci.yml enables revive, gosec, prealloc, misspell, wrapcheck, unparam, nestif, and a number of other linters. CI fails if any of them complain.

Verifying your editor setup

The project is formatted with gofumpt and goimports. Most Go-aware editors will pick this up via .golangci.yml's formatters block, but if you see unrelated diff noise after saving a file, run gofumpt -w . and goimports -w . manually.

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

Getting started – Bubble Tea wiki | Factory