building-glamorous-tuis by Dicklesworthstone
>-
Content & Writing
81 Stars
15 Forks
Updated Jan 19, 2026, 04:39 AM
Why Use This
This skill provides specialized capabilities for Dicklesworthstone's codebase.
Use Cases
- Developing new features in the Dicklesworthstone repository
- Refactoring existing code to follow Dicklesworthstone standards
- Understanding and working with Dicklesworthstone's codebase structure
Install Guide
2 steps- 1
Skip this step if Ananke is already installed.
- 2
Skill Snapshot
Auto scan of skill assets. Informational only.
Valid SKILL.md
Checks against SKILL.md specification
Source & Community
Skill Stats
SKILL.md 300 Lines
Total Files 1
Total Size 0 B
License NOASSERTION
---
name: building-glamorous-tuis
description: >-
Build beautiful terminal UIs with Charmbracelet. For SHELL/BASH scripts: use
Gum (prompts, spinners, selection), VHS (recording), Mods (AI), Freeze
(screenshots), Glow (markdown). For GO applications: use Bubble Tea
(framework), Bubbles (components), Lip Gloss (styling), Huh (forms), Glamour
(markdown), Harmonica (animation). For INFRASTRUCTURE: Wish (SSH apps), Soft
Serve (Git), teatest (testing). Trigger on: shell scripts needing UI, Go CLI
tools, terminal dashboards, SSH applications, or "make this CLI prettier."
---
# 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.Scanf` is 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 |
Name Size