Terminal-UIs mit Charm erstellen
Wenn Sie jemals lazygit, k9s oder htop verwendet haben, wissen Sie, wie sich eine gut gebaute Terminal-Benutzeroberfläche anfühlen kann — responsiv, strukturiert und überraschend elegant. Früher bedeutete der Bau solcher Anwendungen, sich mit ncurses herumzuschlagen oder rohe Escape-Codes zu schreiben. Das Charm-Ökosystem ändert das grundlegend.
Dieser Artikel zeigt, wie Sie Terminal-UIs mit Charm und Go erstellen, mit Fokus auf Bubble Tea und die dazugehörigen Bibliotheken. Die aktuellen Hauptversionen der Charm-Bibliotheken verwenden aktualisierte Go-Modulpfade, was sich in den folgenden Beispielen widerspiegelt. Wenn Sie in Komponenten und State denken, wird Ihnen das mentale Modell sofort vertraut vorkommen.
Wichtigste Erkenntnisse
- Bubble Tea folgt der Elm-Architektur (Model, Update, View), was das State-Management vorhersehbar und komponierbar macht.
- Lip Gloss bietet deklaratives Styling für Terminal-Ausgaben, während Bubbles fertige UI-Komponenten wie Texteingaben, Spinner und Viewports bereitstellt.
- Die Bibliotheken des Charm-Ökosystems lassen sich sauber übereinander schichten, sodass Sie elegante TUIs in Go erstellen können, ohne rohe Escape-Codes oder ncurses zu verwenden.
- Huh und Wish erweitern den Stack um Formulare bzw. SSH-gehostete TUIs.
Was ist eine TUI und warum sollte man eine erstellen?
Ein Terminal User Interface (TUI) ist eine interaktive, visuell strukturierte Anwendung, die innerhalb eines Terminals läuft. Im Gegensatz zu einer einfachen CLI, die einen Befehl entgegennimmt und sich beendet, behält eine TUI ihren Zustand bei, reagiert in Echtzeit auf Tastatureingaben und rendert dynamische Layouts.
TUIs sind sinnvoll, wenn Sie Folgendes benötigen:
- Ein Entwicklerwerkzeug, das über SSH ohne Browser funktioniert
- Geringeren Ressourcenverbrauch als eine Electron-App
- Etwas Skriptfähiges, das sich dennoch elegant anfühlt
Das Charm-Ökosystem im Überblick
Charm pflegt mehrere Bibliotheken, die gut zusammenarbeiten:
| Bibliothek | Rolle |
|---|---|
| Bubble Tea | Anwendungs-Framework (Event-Loop, State) |
| Lip Gloss | Styling und Layout |
| Bubbles | Vorgefertigte UI-Komponenten |
| Huh | Formular- und Eingabe-Primitive |
| Wish | SSH-Server zum Remote-Hosting von TUIs |
Bubble Tea ist der Kern. Alles andere baut darauf auf.
Wie die Architektur von Bubble Tea funktioniert (Model, Update, View)
Bubble Tea folgt der Elm-Architektur, einem Muster, das Frontend-Entwickler von Redux oder Reacts useReducer kennen werden.
Jede Bubble Tea-App definiert drei Dinge:
- Model — Ihr Anwendungszustand
- Update — eine Funktion, die Nachrichten verarbeitet und ein neues Model zurückgibt
- View — eine Funktion, die das Model als Terminal-Ansicht rendert
package main
import (
"fmt"
"log"
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) {
switch msg := msg.(type) {
case tea.KeyPressMsg:
switch msg.String() {
case "up":
m.count++
case "q", "ctrl+c":
return m, tea.Quit
}
}
return m, nil
}
func (m model) View() tea.View {
return tea.NewView(fmt.Sprintf("Count: %d\n(press up to increment, q to quit)", m.count))
}
func main() {
p := tea.NewProgram(model{})
if _, err := p.Run(); err != nil {
log.Fatal(err)
}
}
Beachten Sie den Import-Pfad charm.land/bubbletea/v2. Aktuelle Versionen der Charm-Bibliotheken verwenden charm.land-Modulpfade anstelle der älteren github.com/charmbracelet/*-Imports, die in vielen älteren Tutorials erscheinen.
Layouts und Styling mit Lip Gloss hinzufügen
Lip Gloss kümmert sich um das Styling. Sie definieren Styles als Werte und wenden sie auf Strings an, bevor Sie diese rendern.
import "charm.land/lipgloss/v2"
var titleStyle = lipgloss.NewStyle().
Bold(true).
Foreground(lipgloss.Color("#FF79C6")).
Padding(0, 1)
func (m model) View() tea.View {
return tea.NewView(titleStyle.Render("My TUI App"))
}
Hinweis: Neuere Versionen von Lip Gloss haben die Funktionsweise des adaptiven Farbverhaltens geändert. Hintergrunderkennung und Style-Anpassung werden jetzt expliziter im Anwendungscode gehandhabt, anstatt automatisch von der Bibliothek.
Discover how at OpenReplay.com.
Vorgefertigte Komponenten aus Bubbles verwenden
Bubbles bietet fertige Komponenten — Texteingaben, Spinner, Fortschrittsbalken, Viewports und mehr. Jede Komponente folgt demselben Model/Update/View-Vertrag, sodass Sie sie direkt in Ihr eigenes Model einbetten können.
import "charm.land/bubbles/v2/textinput"
type model struct {
input textinput.Model
}
Diese Komponierbarkeit macht Bubble Tea sauber skalierbar. Sie erstellen kleine, fokussierte Models und komponieren sie zu größeren, genau wie beim Komponieren von Komponenten in einem Frontend-Framework.
Wann Sie zu Huh oder Wish greifen sollten
Wenn Ihre TUI Formulare benötigt — mehrzeilige Eingaben, Bestätigungen, Auswahlmenüs — übernimmt Huh das, ohne dass Sie es von Grund auf neu erstellen müssen. Um eine TUI über SSH zu hosten, damit Benutzer darauf zugreifen können, ohne lokal etwas zu installieren, verpackt Wish Ihr Bubble Tea-Programm in einen SSH-Server.
Erste Schritte
go mod init mytui
go get charm.land/bubbletea/v2
go get charm.land/lipgloss/v2
go get charm.land/bubbles/v2
Führen Sie Ihr Programm aus mit:
func main() {
p := tea.NewProgram(model{})
if _, err := p.Run(); err != nil {
log.Fatal(err)
}
}
Fazit
Der Charm Bubble Tea-Stack bietet Ihnen eine strukturierte, komponierbare Möglichkeit, Terminal-Anwendungen in Go zu erstellen. Das Model/Update/View-Muster hält den State vorhersehbar, Lip Gloss übernimmt das Styling deklarativ, und Bubbles liefert Komponenten, für deren Entwicklung Sie sonst Tage benötigen würden. Wenn Sie mit komponentenbasiertem Frontend-Denken vertraut sind, wird sich das Erstellen von Terminal-UIs mit Charm weniger wie das Erlernen eines neuen Paradigmas anfühlen und mehr wie die Anwendung eines bereits bekannten — nur eben in einem Terminal.
FAQs
Bubble Tea ist eine Go-Bibliothek, daher benötigen Sie zumindest ein grundlegendes Verständnis von Go, um sie zu verwenden. Allerdings ist die von Elm inspirierte Architektur unkompliziert. Wenn Sie mit Konzepten wie State, Nachrichten und Rendering-Funktionen aus einer beliebigen Sprache vertraut sind, können Sie die Go-spezifische Syntax relativ schnell erlernen.
Aktuelle Versionen verwenden charm.land-Modulpfade wie charm.land/bubbletea/v2 anstelle der älteren github.com/charmbracelet-Imports, die in vielen älteren Tutorials zu finden sind. Die Init-Funktion gibt nur einen Befehl zurück, und die View-Funktion gibt eine Terminal-Ansicht anstelle eines rohen Strings zurück.
Ja. Da Update eine reine Funktion ist, die eine Nachricht entgegennimmt und ein neues Model sowie einen Befehl zurückgibt, können Sie Ihre Anwendungslogik durch Unit-Tests prüfen, indem Sie Update direkt mit spezifischen Nachrichten aufrufen und den zurückgegebenen Model-Zustand überprüfen. Die View-Funktion kann ebenfalls getestet werden, indem Sie ihre gerenderte Ausgabe prüfen.
Ja. Die Wish-Bibliothek ermöglicht es Ihnen, jedes Bubble Tea-Programm in einen SSH-Server zu verpacken. Benutzer verbinden sich per SSH und interagieren direkt in ihrem Terminal mit Ihrer TUI, ohne lokal etwas installieren zu müssen. Dies ist nützlich für gemeinsam genutzte Entwicklerwerkzeuge, Dashboards oder interaktive Demos.
Gain Debugging Superpowers
Unleash the power of session replay to reproduce bugs, track slowdowns and uncover frustrations in your app. Get complete visibility into your frontend with OpenReplay — the most advanced open-source session replay tool for developers. Check our GitHub repo and join the thousands of developers in our community.