MCPcopy Index your code
hub / github.com/charmbracelet/bubbles

github.com/charmbracelet/bubbles @v2.1.1

repository ↗ · DeepWiki ↗ · release v2.1.1 ↗ · Ask this repo → · + Follow
685 symbols 2,282 edges 38 files 503 documented · 73% updated todayv2.1.1 · 2026-07-04★ 8,631127 open issues
README

Bubbles

Latest Release GoDoc Build Status Go ReportCard

Primitives for Bubble Tea applications. These components are used in production in Crush, and many other applications.

[!TIP]

Upgrading from v1? Check out the upgrade guide, or point your LLM at it and let it go to town.

Spinner

Spinner Example

A spinner, useful for indicating that some kind an operation is happening. There are a couple default ones, but you can also pass your own ”frames.”

Text Input

Text Input Example

A text input field, akin to an <input type="text"> in HTML. Supports unicode, pasting, in-place scrolling when the value exceeds the width of the element and the common, and many customization options.

Text Area

Text Area Example

A text area field, akin to an <textarea /> in HTML. Allows for input that spans multiple lines. Supports unicode, pasting, vertical scrolling when the value exceeds the width and height of the element, and many customization options.

Table

Table Example

A component for displaying and navigating tabular data (columns and rows). Supports vertical scrolling and many customization options.

Progress

Progressbar Example

A simple, customizable progress meter, with optional animation via Harmonica. Supports solid and gradient fills. The empty and filled runes can be set to whatever you'd like. The percentage readout is customizable and can also be omitted entirely.

Paginator

Paginator Example

A component for handling pagination logic and optionally drawing pagination UI. Supports "dot-style" pagination (similar to what you might see on iOS) and numeric page numbering, but you could also just use this component for the logic and visualize pagination however you like.

Viewport

Viewport Example

A viewport for vertically scrolling content. Optionally includes standard pager keybindings and mouse wheel support. A high performance mode is available for applications which make use of the alternate screen buffer.

This component is well complemented with Reflow for ANSI-aware indenting and text wrapping.

List

List Example

A customizable, batteries-included component for browsing a set of items. Features pagination, fuzzy filtering, auto-generated help, an activity spinner, and status messages, all of which can be enabled and disabled as needed. Extrapolated from [Glow][glow].

File Picker

File picker example

A customizable component for picking a file from the file system. Navigate through directories and select files, optionally limit to certain file extensions.

Timer

A simple, flexible component for counting down. The update frequency and output can be customized as you like.

Timer example

Stopwatch

Stopwatch example

A simple, flexible component for counting up. The update frequency and output can be customized as you see fit.

Help

Help Example

A customizable horizontal mini help view that automatically generates itself from your keybindings. It features single and multi-line modes, which the user can optionally toggle between. It will truncate gracefully if the terminal is too wide for the content.

Key

A non-visual component for managing keybindings. It’s useful for allowing users to remap keybindings as well as generating help views corresponding to your keybindings.

type KeyMap struct {
    Up key.Binding
    Down key.Binding
}

var DefaultKeyMap = KeyMap{
    Up: key.NewBinding(
        key.WithKeys("k", "up"),        // actual keybindings
        key.WithHelp("↑/k", "move up"), // corresponding help text
    ),
    Down: key.NewBinding(
        key.WithKeys("j", "down"),
        key.WithHelp("↓/j", "move down"),
    ),
}

func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
    switch msg := msg.(type) {
    case tea.KeyPressMsg:
        switch {
        case key.Matches(msg, DefaultKeyMap.Up):
            // The user pressed up
        case key.Matches(msg, DefaultKeyMap.Down):
            // The user pressed down
        }
    }
    return m, nil
}

There’s more where that came from

To check out community-maintained Bubbles see Charm & Friends. Made a cool Bubble that you want to share? PRs are welcome!

Contributing

See contributing.

Feedback

We’d love to hear your thoughts on this project. Feel free to drop us a note!

License

MIT


Part of Charm.

The Charm logo

Charm热爱开源 • Charm loves open source

Extension points exported contracts — how you extend this code

KeyMap (Interface)
KeyMap is a map of keybindings used to generate help. Since it's an interface it can be any type, though struct or a map [3 …
help/help.go
ItemDelegate (Interface)
ItemDelegate encapsulates the general functionality for all list items. The benefit to separating this logic from the it [2 …
list/list.go
Hasher (Interface)
Hasher is an interface that requires a Hash method. The Hash method is expected to return a string representation of the [1 …
internal/memoization/memoization.go
Sanitizer (Interface)
Sanitizer is a helper for bubble widgets that want to process Runes from input key messages. [1 implementers]
internal/runeutil/runeutil.go
ColorFunc (FuncType)
ColorFunc is a function that can be used to dynamically fill the progress bar based on the current percentage. total is
progress/progress.go
Option (FuncType)
Option is used to set options in New.
paginator/paginator.go
Option (FuncType)
Option is a configuration option in [New]. For example: timer := New(time.Second*10, WithInterval(5*time.Second))
stopwatch/stopwatch.go
Option (FuncType)
Option is used to set options in New. For example: table := New(WithColumns([]Column{{Title: "ID", Width: 10}}))
table/table.go

Core symbols most depended-on inside this repo

NewBinding
called by 88
key/key.go
Update
called by 87
list/list.go
WithKeys
called by 83
key/key.go
Matches
called by 82
key/key.go
Render
called by 78
list/list.go
Height
called by 74
list/list.go
WithHelp
called by 69
key/key.go
SetWidth
called by 59
textarea/textarea.go

Shape

Method 396
Function 188
Struct 69
FuncType 13
TypeAlias 13
Interface 6

Languages

Go100%

Modules by API surface

textarea/textarea.go99 symbols
list/list.go96 symbols
viewport/viewport.go60 symbols
textinput/textinput.go57 symbols
table/table.go45 symbols
textarea/textarea_test.go36 symbols
progress/progress.go29 symbols
filepicker/filepicker.go24 symbols
timer/timer.go20 symbols
stopwatch/stopwatch.go19 symbols
paginator/paginator.go19 symbols
cursor/cursor.go18 symbols

Dependencies from manifests, versioned

github.com/MakeNowJust/heredocv1.0.0 · 1×
github.com/atotto/clipboardv0.1.4 · 1×
github.com/aymanbagabas/go-udiffv0.4.1 · 1×
github.com/charmbracelet/colorprofilev0.4.3 · 1×
github.com/charmbracelet/harmonicav0.2.0 · 1×
github.com/charmbracelet/ultravioletv0.0.0-2026052513223 · 1×
github.com/charmbracelet/x/ansiv0.11.7 · 1×
github.com/charmbracelet/x/exp/goldenv0.0.0-2025080622240 · 1×
github.com/charmbracelet/x/termv0.2.2 · 1×
github.com/charmbracelet/x/termiosv0.1.1 · 1×

For agents

$ claude mcp add bubbles \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact