Bubble Tea is based on the functional design paradigms of The Elm Architecture, which happens to work nicely with Go. It's a delightful way to build applications.
Bubble Tea programs are comprised of a model that describes the application state and three simple methods on that model:
A function that returns an initial command for the application to run. This is where you set up your initial state.
func (m model) Init() (tea.Model, tea.Cmd) {
// Set up initial state
return m, nil
}
A function that handles incoming events and updates the model accordingly. Think of this as your event handler.
func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
switch msg := msg.(type) {
case tea.KeyPressMsg:
switch msg.String() {
case "q", "ctrl+c":
return m, tea.Quit
}
}
return m, nil
}
A function that renders the UI based on the data in the model. It returns a string that represents your entire UI.
func (m model) View() string {
return "Hello, Bubble Tea!"
}
The model describes your application's state. It can be any type, but a struct usually makes the most sense:
type model struct {
choices []string // items on the to-do list
cursor int // which item our cursor is pointing at
selected map[int]struct{} // which items are selected
}
Messages are events. They can be keypresses, mouse events, timer ticks, or anything else you define:
switch msg := msg.(type) {
case tea.KeyPressMsg:
// Handle key press
case tea.MouseMsg:
// Handle mouse event
case tickMsg:
// Handle custom tick message
}
Commands are functions that perform I/O and return a message. They're how you handle side effects:
func checkServer() tea.Msg {
res, err := http.Get("https://api.example.com")
if err != nil {
return errMsg{err}
}
return statusMsg(res.StatusCode)
}
// Use it in Update:
return m, checkServer
Here's the flow:
graph LR
A[Init] --> B[View]
B --> C[User Input]
C --> D[Update]
D --> B
D --> E[Commands]
E --> D
Init sets up your initial model and optional commandView renders based on the current modelUpdateUpdate returns a new model and optional commands