Перейти к содержимому
ГоМастер

Поиск по урокам

Найдите урок, курс, термин или раздел

Урок 1 из 25 ~16 мин +50 XP

Знакомство с Bubble Tea: интерфейсы в терминале

Bubble Tea — библиотека bubbletea go из экосистемы Charmbracelet: на ней сделаны gh-dash, gum и сотни других TUI-приложений. Разберём, зачем терминалу собственные интерфейсы, кто уже строит на этом фреймворке свои инструменты и почему в его сердце лежит elm архитектура, пришедшая из фронтенда.

Содержание урока · 12 разделов

Половина рабочего дня разработчика проходит в терминале — и всё же самые любимые инструменты там не «печатают строчки», а живут: k9s рисует таблицы подов и отвечает на клавиши, lazygit превращает git в навигацию стрелками, gh-dash показывает pull request'ы как ленту интерфейса, а не плоскую выдачу curl. Разница не в красоте, а в модели: скрипт печатает и умирает, интерфейс держит состояние, ждёт события и перерисовывается. Bubble Tea — способ писать такие программы на Go без борьбы с ANSI-кодами и сырыми потоками ввода. Экраны этого курса можно потрогать в песочнице урока — там вкладка с виртуальным терминалом; полноценные же программы всё равно запускаются локально, потому что настоящему TUI нужен настоящий терминал. Сначала посмотрим на ландшафт: кто, зачем и на чём.

Bubble Tea — TUI go библиотека: что под капотом#

Bubble Tea — фреймворк для терминальных интерфейсов на чистом Go: пакет bubbletea go-проект подключает одной строкой импорта — github.com/charmbracelet/bubbletea. Автор — компания Charmbracelet Кристиана Рочи, фреймворк вышел в 2020 году и с тех пор перерос статус эксперимента: сегодня это де-факто стандартный ответ на вопрос «как сделать TUI-приложение на Go». «Чистый Go» здесь важное слово: без cgo, без зависимости от ncurses, со статическим бинарником на выходе. Программа работает по SSH ровно так же, как локально, — терминал есть терминал. Идею подсмотрели у Elm и Haskell: архитектура Model-Update-View оказалась настолько удачной, что фреймворк прижился далеко за пределами своей ниши. Отрисовка устроена экономно: после каждого события фреймворк сравнивает новый кадр со старым и обновляет только изменившиеся строки — на типичный инструмент это стоит микросекунды. API ядра годами живёт в первой мажорной версии — примеры из туториалов двухлетней давности собираются без правок. Сам фреймворк намеренно мал: он берёт на себя цикл событий, ввод и отрисовку, а компоненты, стили и формы вынесены в соседние библиотеки — до них дойдём ниже.

Кто строит на Bubble Tea#

  • gh-dash (dlvhdr/gh-dash) — популярное расширение GitHub CLI: список PR и issues с фильтрами, деталями и ревью прямо в терминале
  • gum от Charm — набор готовых бинарников для shell-скриптов: выбор, ввод, подтверждение, спиннеры; внутри каждого — Bubble Tea
  • Soft Serve — git-сервер с TUI-панелью управления, тоже из Charmbracelet
  • AWS Copilot CLI — интерактивные подсказки и панели деплоя построены на Bubble Tea, Charm публиковал об этом отдельный кейс
  • k9s — знаменитая панель Kubernetes на самом деле сделана на tview, не на Bubble Tea; класс задач тот же, а путают их часто
  • Сотни утилит в подборках awesome-tui: мониторы, чаты, менеджеры задач, интерактивные генераторы — и внутренние инструменты команд, которых нет в подборках

TUI против GUI и CLI: где место Bubble Tea#

Способов дать пользователю интерфейс три, и у каждого своя ниша. CLI печатает, ждёт ввод и завершается — идеально для пайплайнов и автоматизации. GUI (например, на fyne — у нас есть отдельный курс: знакомство с Fyne) даёт окна и мышь, но требует дисплея, графических библиотек и сборки под каждую платформу. TUI-приложение живёт посередине: оно реагирует на клавиши и мышь, как GUI, но рисуется символами и работает там, куда GUI не доберётся — на сервере без иксов, в docker-контейнере, в SSH-сессии с ноутбука. Моё правило: инструмент для разработчиков, который обязан запускаться на сервере, — почти всегда кандидат на TUI. Нужны курсор, файловый диалог и пиксели — берите GUI и не мучайте терминал, он этого не простит.

Зачем elm архитектура в терминале#

Классический GUI-фреймворк предлагает колбэки: кнопка нажата — вызовись сюда, таймер тикнул — сюда. На форме из трёх полей это терпимо. На панели с десятью экранами колбэки начинают менять состояние кто попало и в каком попало порядке, а отладка превращается в археологию: кто именно испортил поле модели, ищется часами. Elm-архитектура (та самая, из языка Elm; Redux — её младший родственник) разрешает проблему жёстко. Всё состояние приложения живёт в одном значении — модели. Каждое событие — обычное значение-сообщение. Единственная функция Update получает сообщение и возвращает новую модель. Единственная функция View рисует модель в строку. Никаких скрытых мутаций из четырёх углов программы: поток «событие → Update → View» один, и он помещается в голову целиком. Для терминала это совпадение особенно удачно — событий много, и все они асинхронные: клавиши, мышь, resize окна, ответы сети, таймеры.

Первый взгляд: программа целиком

GO
package main

import (
        "fmt"
        "os"

        "github.com/charmbracelet/bubbletea"
)

type model struct {
        count int
}

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

func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
        switch msg := msg.(type) {
        case tea.KeyMsg:
                switch msg.String() {
                case "up":
                        m.count++
                case "down":
                        m.count--
                case "q", "ctrl+c":
                        return m, tea.Quit
                }
        }
        return m, nil
}

func (m model) View() string {
        return fmt.Sprintf(
                "Счёт: %d\n\n↑ больше, ↓ меньше, q — выход\n",
                m.count,
        )
}

func main() {
        if _, err := tea.NewProgram(model{}).Run(); err != nil {
                fmt.Println("Ошибка:", err)
                os.Exit(1)
        }
}

Вся программа — три метода и одна строка запуска. Init() объявляет, что нужно сделать при старте (здесь — ничего), Update получает любое событие и переключается по его типу, View рисует модель в строку, а фреймворк сам печатает её и перерисовывает при изменениях. Ветки q и ctrl+c возвращают tea.Quit — команду завершить цикл. tea.NewProgram создаёт программу, Run блокирует main до выхода. В песочнице сайта этот код не запустится: Bubble Tea требует настоящий терминал. Локально — go mod init, go get github.com/charmbracelet/bubbletea, go run main.go.

Экосистема Charm: bubbles, lipgloss и компания#

Bubble Tea — не одинокая библиотека, а центр целой экосистемы. bubbles — официальный набор компонентов: список с фильтрацией, текстовые поля, таблицы, спиннеры, прогресс-бары. Всё это тоже модели, встраиваемые в вашу, — в курсе им посвящено несколько уроков, включая готовые списки. Lip Gloss — стилизация: цвета, рамки, отступы, выравнивание; верстка терминального интерфейса, предсказуемая как CSS с жёсткими правилами — основы разберём в отдельном уроке. Дальше по списку: glamour рендерит markdown в терминале, huh собирает формы, gum предлагает готовые команды для скриптов, vhs записывает демо-гифки. Практический вывод: прежде чем писать список задач своими руками, проверьте bubbles; прежде чем собирать ANSI-коды цветов конкатенацией, откройте Lip Gloss. Обе проблемы давно решены, и решены лучше, чем получится с первого раза у вас.

Карта экосистемы Charm#

Пакет или проектЧто делаетКогда пригождается
bubbleteaядро: цикл событий, Model, Update, View, вводкаркас любого TUI-приложения
bubblesготовые компоненты: list, textinput, table, spinner, progressчтобы не писать список задач самому
lipglossцвета, рамки, отступы, выравниваниелюбой интерфейс сложнее одной строки
glamourрендер markdown в терминалепросмотр README, справки, changelog
huhформы: поля, выбор, подтверждениямастера настройки, ввод данных
vhsзапись GIF из сценария терминаладемо для README проекта

Терминал как платформа: что он умеет#

Недооценённый факт: современный терминал — платформа с возможностями, о которых GUI-разработчик даже не задумывается. Он умеет цвета и стили — 256 цветов и truecolor почти везде, юникодную графику для рамок, события resize окна, а с включённым режимом — даже мышь: клики, движение, колесо. Bubble Tea берёт всё это на себя: фреймворк переводит терминал в нужные режимы, читает сырые байты ввода, собирает их в понятные сообщения и перерисовывает только изменившиеся строки. Вам остаются три метода и здравый смысл. Обратная сторона: у терминала есть причуды. Одни и те же комбинации клавиш в разных эмуляторах приходят по-разному, поддержка мыши зависит от самого эмулятора, а что-то не различается в принципе. Это не баг фреймворка, а природа платформы: вы пишете не под операционную систему, а под сотню эмуляторов от macOS Terminal до Windows Terminal. Капризы клавиатуры подробно разберём в четвёртом уроке курса. Здесь же отметим только приятное: всё это богатство доступно без единой строчки кода настройки — вы подключаете пакет и сразу работаете с сообщениями, а не с байтами и ioctl.

Почему не ncurses и не tview#

Выбор у Go-разработчика шире, и честнее обсудить альтернативы сразу. ncurses — C-библиотека возрастом в десятилетия: мощная, но с cgo, ручным управлением окнами и чуждым Go циклом жизни. tview — зрелый виджетный фреймворк, на нём сделан k9s: таблицы, деревья и формы доступны из коробки, модель событий ближе к классическим GUI. Bubble Tea берёт другим: крошечное ядро, View — просто строка, вся логика — чистые функции над состоянием. Спорный момент скажу честно: перерисовывать весь View после каждого события выглядит расточительно, и я долго относился к этому скептически, ожидая мерцания и тормозов. Практика умерила пыл в обе стороны. Перерисовка на деле дешевле, чем кажется, — фреймворк обновляет только изменившиеся строки. Но для гигантских таблиц на десятки тысяч строк разница достижима: замеряйте, прежде чем строить монолит на одном экране. Для типичного инструмента — панели, чата, меню — запас прочности огромный.

Проверка: кто есть кто

Какой из этих инструментов построен на Bubble Tea?

Проверка: специфика TUI

Чем TUI-приложение принципиально отличается от GUI?

Что нарисует View?

Прочитайте код и выберите, что он выведет:

type model struct{ count int }

func initialModel() model { return model{count: 1} }

func (m model) View() string {
        return fmt.Sprintf("Счёт: %d\n", m.count)
}

// Пользователь нажал: ↑, ↓, ↑, ↑

Восстановите каркас программы

Впишите недостающие детали: имя пакета, путь импорта, метод старта и команду выхода.

package import ( "fmt" "github.com//bubbletea" ) func (m model) () tea.Cmd { return nil } func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { // ... обработка событий ... case "q": return m, tea. }

Соберите минимальный каркас

Расставьте строки каркаса Bubble Tea в правильном порядке — от объявления пакета до запуска. Метод View не случайно отсутствует: его добавим во втором уроке, а пока просто восстановите порядок остальных частей.

Строки

Ваша программа

Нажимайте на строки слева, чтобы собрать программу

Карточки: словарь Bubble Tea

Термин

Bubble Tea

нажмите, чтобы перевернуть
Определение

Фреймворк терминальных интерфейсов от Charmbracelet (Go, 2020): цикл событий, Model, Update, View — и ничего лишнего.

1 / 6

Что дальше по курсу#

Дальше — практика. Второй урок собирает счётчик целиком: каждая строка Model, Update и View с разбором и типичными ошибками новичка. Третий — про tea.Program: полный экран, мышь, отправка сообщений снаружи и то, как программа завершается. Потом придут команды tea.Cmd для асинхронных операций и компоненты bubbles. Полная программа — 25 уроков от «Hello, TUI» до итоговой панели задач — лежит на странице курса Bubble Tea. И напомню про запуск: примеры рассчитаны на локальный Go и настоящий терминал. Установить зависимость и собрать программу занимает минут пять, а ощущение живого интерфейса на собственном экране не заменит ни один скринкаст.

Песочница урока

Редактируйте код и запускайте его прямо здесь — интерпретатор работает в браузере, ничего устанавливать не нужно. За каждый запуск — +2 XP.

Виртуальный терминал

модель Bubble Tea · Model → Update → View

Отредактируйте модель, Update или View — и нажмите «Собрать модель»: код разберётся и начнёт отвечать на клавиши, как настоящий tea.Program.

виртуальный терминал · bubbleteaalt-screen
Шаг 1 из 3
TUI живёт прямо в терминале
enter — далее, backspace — назад, q — выход

Клавиатура — обработано в Update

Журнал программы

модель собрана: steps []string (3) · step int = 0

программа работает — нажмите клавишу ниже

Коротко: что запомнить

  • Bubble Tea — фреймворк TUI от Charmbracelet (Go, 2020): цикл событий, Model, Update, View и ничего лишнего.
  • Elm-архитектура: всё состояние в модели, события — сообщения, Update возвращает новую модель, View рисует строку.
  • На Bubble Tea сделаны gh-dash, gum, Soft Serve и AWS Copilot CLI; k9s — сосед на tview, класс задач тот же.
  • TUI занимает нишу между CLI и GUI: интерактивность как у GUI, но работает по SSH без дисплея.
  • Экосистема: bubbles — компоненты, Lip Gloss — стили; рядом glamour, huh, gum, vhs.
  • Перерисовка всего View после каждого события дешевле, чем кажется; для гигантских таблиц — замеряйте.
  • Примеры курса запускаются локально: нужен настоящий терминал, песочница показывает логику на виртуальном.

Домашнее задание

Установите Bubble Tea локально: mkdir tui-lab, затем go mod init tui-lab и go get github.com/charmbracelet/bubbletea. Соберите программу из урока, запустите и понажимайте стрелки. Потом сломайте её нарочно: уберите ветку ctrl+c и попробуйте выйти. Опишите словами, что происходит и почему — этот вывод понадобится в четвёртом уроке.

Личные заметкиПусто
Хранятся только в вашем браузере (Bubble Tea · Знакомство с Bubble Tea: интерфейсы в терминале)

Вопросы и ответы по уроку

Что такое Bubble Tea простыми словами?

Библиотека для Go, которая превращает терминал в платформу для интерфейсов: собирает клавиши и события в понятные сообщения, а вам оставляет три метода — модель состояния, обновление и отрисовку строки.

Чем Bubble Tea отличается от tview?

tview — виджетный фреймворк, близкий к классическим GUI: таблицы и формы из коробки, модель событий с колбэками. Bubble Tea — Elm-архитектура с чистыми функциями над состоянием: меньше готовых виджетов, больше дисциплины состояния, проще тесты и предсказуемый поток данных.

Можно ли запускать Bubble Tea программы по SSH?

Да, это одна из главных причин брать TUI: программа рисуется символами и требует только терминал. Соберите статический бинарник, положите на сервер — интерфейс работает в SSH-сессии без установки зависимостей.

Термины урока

Ключевые понятия из этого урока — короткие определения в глоссарии. Наведите на термин, чтобы вспомнить, откройте карточку для подробностей и ссылки на практику.

Сравните с альтернативами

Практический вопрос после первых уроков: а почему именно эта библиотека? Мы разобрали конкурентов по одним критериям, с кодом одной задачи рядом и персональным подбором под ваши приоритеты.

Следующая ступень учебного пути

Zap25 уроков~9 чпрактика25 уроков уже доступны

Zap: структурное логирование на Go

Интерактивный курс Zap — быстрого логгера для Go: уровни, поля, JSON, ротация, интеграции с Gin, GORM и gRPC. 25 уроков с примерами и итоговым проектом.

  • Писать структурные логи с полями вместо строк
  • Выбирать между Logger и SugaredLogger осознанно
  • Настраивать энкодеры, выводы и ротацию файлов
  • Разбираться в zapcore: Core, Encoder, WriteSyncer, LevelEnabler