building-glamorous-tuis
π―Skillfrom dicklesworthstone/meta_skill
building-glamorous-tuis skill from dicklesworthstone/meta_skill
Part of
dicklesworthstone/meta_skill(2 items)
Installation
cargo install --path .cargo run -- <COMMAND>cargo install --git https://github.com/Dicklesworthstone/beads_viewerSkill Details
>-
Overview
# Building Glamorous TUIs with Charmbracelet
Quick Router
What are you building?
| Context | Solution | Reference |
|---------|----------|-----------|
| Shell/Bash script | Gum, VHS, Mods, Freeze | [β Shell Scripts](#for-shell-scripts) |
| Go CLI/TUI | Bubble Tea + Lip Gloss | [β Go TUI](#for-go-applications) |
| SSH-accessible app | Wish + Bubble Tea | [β Infrastructure](#for-infrastructure) |
| Recording demos | VHS | [β Shell Scripts](#vhs-quick-start) |
| Testing TUIs | teatest | [β Infrastructure](#for-infrastructure) |
---
For Shell Scripts
No Go required. Gum gives you all the UI primitives.
```bash
brew install gum
```
Essential Gum Commands
```bash
# Input
NAME=$(gum input --placeholder "Your name")
# Selection (single)
COLOR=$(gum choose "red" "green" "blue")
# Selection (multi)
ITEMS=$(gum choose --no-limit "a" "b" "c")
# Fuzzy filter (from stdin)
BRANCH=$(git branch | gum filter)
# Confirmation
gum confirm "Continue?" && echo "yes"
# Spinner
gum spin --title "Working..." -- long-command
# Styled output
gum style --border rounded --padding "1 2" "Hello"
# File picker
FILE=$(gum file .)
```
Quick Recipe: Git Commit
```bash
TYPE=$(gum choose "feat" "fix" "docs" "refactor")
MSG=$(gum input --placeholder "commit message")
gum confirm "Commit?" && git commit -m "$TYPE: $MSG"
```
VHS Quick Start
Record terminal β GIF:
```bash
brew install vhs
cat > demo.tape << 'EOF'
Output demo.gif
Set Theme "Catppuccin Mocha"
Type "echo hello"
Enter
Sleep 1s
EOF
vhs demo.tape
```
Other Shell Tools
| Tool | Install | One-liner |
|------|---------|-----------|
| Mods | brew install mods | git diff \| mods "review this" |
| Glow | brew install glow | glow README.md |
| Freeze | brew install freeze | freeze code.go -o screenshot.png |
[Full Shell Reference β](references/shell-scripts.md)
---
For Go Applications
Instant Start
```bash
go get github.com/charmbracelet/bubbletea \
github.com/charmbracelet/lipgloss
```
Minimal TUI (Copy & Run)
```go
package main
import (
"fmt"
tea "github.com/charmbracelet/bubbletea"
"github.com/charmbracelet/lipgloss"
)
var highlight = lipgloss.NewStyle().Foreground(lipgloss.Color("212")).Bold(true)
type model struct {
items []string
cursor 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 "q", "ctrl+c":
return m, tea.Quit
case "up", "k":
if m.cursor > 0 { m.cursor-- }
case "down", "j":
if m.cursor < len(m.items)-1 { m.cursor++ }
case "enter":
fmt.Printf("Selected: %s\n", m.items[m.cursor])
return m, tea.Quit
}
}
return m, nil
}
func (m model) View() string {
s := ""
for i, item := range m.items {
if i == m.cursor {
s += highlight.Render("βΈ "+item) + "\n"
} else {
s += " " + item + "\n"
}
}
return s + "\n(β/β move, enter select, q quit)"
}
func main() {
m := model{items: []string{"Option A", "Option B", "Option C"}}
tea.NewProgram(m).Run()
}
```
Library Cheat Sheet
| Need | Library | Example |
|------|---------|---------|
| TUI framework | bubbletea | tea.NewProgram(model).Run() |
| Components | bubbles | list.New(), textinput.New() |
| Styling | lipgloss | style.Foreground(lipgloss.Color("212")) |
| Forms (simple) | huh | huh.NewInput().Title("Name").Run() |
| Markdown | glamour | glamour.Render(md, "dark") |
| Animation | harmonica | harmonica.NewSpring() |
Quick Patterns
Styled Output (no TUI):
```go
style := lipgloss.NewStyle().Foreground(lipgloss.Color("205")).Bold(true)
fmt.Println(style.Render("Hello!"))
```
Simple Form (no TUI):
```go
var name string
huh.NewInput().Title("Your name?").Value(&name).Run()
```
Confirmation:
```go
var ok bool
huh.NewConfirm().Title("Delete?").Value(&ok).Run()
```
[Full Go TUI Reference β](references/go-tui.md)
[Component API β](references/component-catalog.md)
[Advanced Patterns β](references/advanced-patterns.md)
---
For Infrastructure
Wish: SSH Apps
Serve TUI over SSH:
```go
s, _ := wish.NewServer(
wish.WithAddress(":2222"),
wish.WithHostKeyPath(".ssh/key"),
wish.WithMiddleware(
bubbletea.Middleware(handler),
logging.Middleware(),
),
)
s.ListenAndServe()
```
Connect: ssh localhost -p 2222
Other Infrastructure
| Tool | Purpose | Install |
|------|---------|---------|
| Soft Serve | Self-hosted Git | brew install soft-serve |
| Pop | Send email | brew install pop |
| Skate | Key-value store | brew install skate |
| Melt | SSH key backup | brew install melt |
| Wishlist | SSH gateway | go install github.com/charmbracelet/wishlist |
Testing TUIs
```go
tm := teatest.NewTestModel(t, model)
tm.Send(tea.KeyMsg{Type: tea.KeyEnter})
tm.Type("hello")
teatest.WaitFor(t, tm, func(b []byte) bool {
return strings.Contains(string(b), "expected")
})
```
[Full Infrastructure Reference β](references/infrastructure.md)
---
Decision Guide
```
Is it a shell script?
ββ Yes β Use Gum
β Need recording? β VHS
β Need AI? β Mods
β
ββ No (Go application)
β
ββ Just need styled output?
β ββ Lip Gloss only (no Bubble Tea)
β
ββ Need simple prompts/forms?
β ββ Huh standalone
β
ββ Need full interactive TUI?
β ββ Bubble Tea + Bubbles + Lip Gloss
β
ββ Need SSH access?
ββ Wish + Bubble Tea
```
---
When NOT to Use Charm
- Output is piped:
mytool | grepβ plain text - CI/CD: No terminal β use flags/env vars
- One simple prompt: Maybe
fmt.Scanfis fine
Escape hatch:
```go
if !term.IsTerminal(os.Stdin.Fd()) || os.Getenv("NO_TUI") != "" {
runPlainMode()
return
}
```
---
All References
| Reference | Contents |
|-----------|----------|
| [Shell Scripts](references/shell-scripts.md) | Gum, VHS, Mods, Freeze, Glow - complete |
| [Go TUI](references/go-tui.md) | Bubble Tea patterns, debugging, anti-patterns |
| [Infrastructure](references/infrastructure.md) | Wish, Soft Serve, teatest, x/term |
| [Component Catalog](references/component-catalog.md) | All Bubbles components API |
| [Advanced Patterns](references/advanced-patterns.md) | Theming, layouts, production architecture |