Loading...
Loading...
Reviews BubbleTea TUI code for proper Elm architecture, model/update/view patterns, and Lipgloss styling. Use when reviewing terminal UI code using charmbracelet/bubbletea.
npx skill4agent add existential-birds/beagle bubbletea-code-review| Issue Type | Reference |
|---|---|
| Elm architecture, tea.Cmd as data | references/elm-architecture.md |
| Model state, message handling | references/model-update.md |
| View rendering, Lipgloss styling | references/view-styling.md |
| Component composition, Huh forms | references/composition.md |
| Bubbles components (list, table, etc.) | references/bubbles-components.md |
| Pattern | Why It's Correct |
|---|---|
| |
Value receiver on | Standard BubbleTea pattern; model returned by value |
Nested | Normal component composition |
Helper functions returning | Creates command descriptor, no I/O in Update |
| Commands execute concurrently by runtime |
| Pattern | Why It's Wrong |
|---|---|
| Blocks UI thread |
| Network I/O blocks |
| Freezes UI |
| May block indefinitely |
| Blocking call |
tea.Cmd// BAD - mutates model
func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
m.items = append(m.items, newItem) // mutation!
return m, nil
}
// GOOD - returns new model
func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
newItems := make([]Item, len(m.items)+1)
copy(newItems, m.items)
newItems[len(m.items)] = newItem
m.items = newItems
return m, nil
}// BAD - blocking in Update
func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
data, _ := os.ReadFile("config.json") // blocks UI!
m.config = parse(data)
return m, nil
}
// GOOD - use commands
func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
return m, loadConfigCmd()
}
func loadConfigCmd() tea.Cmd {
return func() tea.Msg {
data, err := os.ReadFile("config.json")
if err != nil {
return errMsg{err}
}
return configLoadedMsg{parse(data)}
}
}// BAD - creates new style each render
func (m Model) View() string {
style := lipgloss.NewStyle().Bold(true).Foreground(lipgloss.Color("205"))
return style.Render("Hello")
}
// GOOD - define styles at package level or in model
var titleStyle = lipgloss.NewStyle().Bold(true).Foreground(lipgloss.Color("205"))
func (m Model) View() string {
return titleStyle.Render("Hello")
}