Charm Bracelet
Examples

Window Title

What This Example Shows

This example demonstrates how to dynamically set the terminal window title in a Bubble Tea program.
The app changes the terminal’s title to "Bubble Tea Example" when it starts, then waits for the user to press any key to quit.

The key here is tea.SetWindowTitle("...") – Bubble Tea sends the correct escape sequence to your terminal to update its title.

Understanding Terminal Window Titles

Many terminal emulators support escape sequences that let programs set the terminal’s title.
That’s why when you run apps like ssh, vim, or htop, the title bar of your terminal often changes automatically.

This is great for giving context to users. For example, your app could set the title to show the current status, mode, or file being worked on.

Here’s what happens in this example:

  • The program starts and immediately sets the terminal’s title
  • The user sees "Bubble Tea Example" in their terminal title bar
  • The app waits until a key is pressed, then quits

How It Works

Initialize With a Title

The Init function sets the title right away:

func (m model) Init() tea.Cmd {
    return tea.SetWindowTitle("Bubble Tea Example")
}

This runs once when the app starts and updates the terminal’s title.

</Step>

<Step>

### Wait for User Input

The `Update` function listens for any keypress:

```go
func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
    switch msg.(type) {
    case tea.KeyMsg:
        return m, tea.Quit
    }
    return m, nil
}

If a key is pressed, the program exits cleanly.

Show a Simple View

The View tells users how to quit:

func (m model) View() string {
    return "\nPress any key to quit."
}

Not every terminal emulator supports window titles.
Most modern ones (like iTerm2, GNOME Terminal, Kitty, and Alacritty) do, but minimal or embedded terminals may ignore it.

Code Breakdown

The model is empty because we don’t need to store any state:

type model struct{}

Its only job is to implement the Bubble Tea Model interface.

The main function starts the Bubble Tea program:

func main() {
    if _, err := tea.NewProgram(model{}).Run(); err != nil {
        fmt.Println("Uh oh:", err)
        os.Exit(1)
    }
}

The Init method sets the window title immediately:

func (m model) Init() tea.Cmd {
    return tea.SetWindowTitle("Bubble Tea Example")
}

The Update handles quitting when any key is pressed:

func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
    switch msg.(type) {
    case tea.KeyMsg:
        return m, tea.Quit
    }
    return m, nil
}

The View

The view just shows instructions for the user:

func (m model) View() string {
    return "\nPress any key to quit."
}

Simple and direct.

Final Code

main.go
package main

import (
	"fmt"
	"os"

	tea "github.com/charmbracelet/bubbletea"
)

type model struct{}

func (m model) Init() tea.Cmd {
	return tea.SetWindowTitle("Bubble Tea Example")
}

func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
	switch msg.(type) {
	case tea.KeyMsg:
		return m, tea.Quit
	}
	return m, nil
}

func (m model) View() string {
	return "\nPress any key to quit."
}

func main() {
	if _, err := tea.NewProgram(model{}).Run(); err != nil {
		fmt.Println("Uh oh:", err)
		os.Exit(1)
	}
}

How is this guide?