Use this file to discover all available pages before exploring further.
Messages (Msgs) are the events that drive your Bubble Tea application. Every interaction, timer tick, HTTP response, and system event becomes a message that flows through your Update method.
type Key struct { // Text contains the actual characters received Text string // Mod represents modifier keys (Ctrl, Alt, Shift, etc.) Mod KeyMod // Code represents the key pressed Code rune // ShiftedCode is the shifted key (e.g., 'A' when shift+a) ShiftedCode rune // BaseCode is the key on a standard PC-101 layout BaseCode rune // IsRepeat indicates if key is being held down IsRepeat bool}
Common Key Codes:
tea.KeyEnter // Enter/Return keytea.KeySpace // Space bartea.KeyBackspace // Backspacetea.KeyTab // Tabtea.KeyEsc // Escape// Arrow keystea.KeyUptea.KeyDowntea.KeyLefttea.KeyRight// Function keystea.KeyF1 through tea.KeyF63// Special keystea.KeyHometea.KeyEndtea.KeyPgUptea.KeyPgDowntea.KeyDeletetea.KeyInsert
// MouseMsg represents a mouse message. This is a generic mouse message that// can represent any kind of mouse event.type MouseMsg interface { fmt.Stringer Mouse() Mouse}
// QuitMsg signals that the program should quit.type QuitMsg struct{}// Quit is a special command that tells the Bubble Tea program to exit.func Quit() Msg { return QuitMsg{}}
Usage:
case tea.KeyPressMsg: if msg.String() == "q" { return m, tea.Quit // Returns a command that sends QuitMsg }case tea.QuitMsg: // Handle cleanup before quitting return m, nil
Sent when the program is suspended (Ctrl+Z) and resumed.From tea.go:543-558:
// SuspendMsg signals the program should suspend.type SuspendMsg struct{}func Suspend() Msg { return SuspendMsg{}}// ResumeMsg can be listened to do something once a program is resumed back// from a suspend state.type ResumeMsg struct{}
Example:
case tea.SuspendMsg: // Save state before suspending m.saveState() return m, tea.Suspendcase tea.ResumeMsg: // Refresh after resuming return m, m.fetchLatestData()
type state intconst ( stateLoading state = iota stateReady stateError)type stateChangeMsg struct { newState state}func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { switch msg := msg.(type) { case stateChangeMsg: m.state = msg.newState switch msg.newState { case stateLoading: return m, loadData() case stateReady: return m, nil case stateError: return m, nil } } return m, nil}
// Goodswitch msg := msg.(type) {case tea.KeyPressMsg: // msg is now KeyPressMsg}// Bad - loses type informationswitch msg.(type) {case tea.KeyPressMsg: // msg is still tea.Msg}
Handle All Cases
Always have a default case that returns the model unchanged:
func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { switch msg := msg.(type) { case myMsg: // Handle default: // Don't drop messages you don't recognize } return m, nil}
Keep Messages Simple
Messages should be plain data - no methods, no behavior:
// Goodtype userLoadedMsg struct { user User}// Bad - too much behaviortype userLoadedMsg struct { user User}func (m userLoadedMsg) Process() { /* ... */ }
Document Custom Messages
Add comments explaining when and why messages are sent:
// tickMsg is sent every second to update the countdown timer.type tickMsg time.Time// dataLoadedMsg is sent when the API request completes successfully.type dataLoadedMsg struct { items []Item}