This package (github.com/SCKelemen/tui) is deprecated.
Use github.com/SCKelemen/tui/v2 instead.
v2 provides the same components organized into focused sub-packages:
agent, chart, chat, container, display, input, nav, selection, style
See the v2 README for migration guide and API reference.
Terminal UI component library built on Bubble Tea with design token theming.
go get github.com/SCKelemen/tui- 25+ interactive components
- Design token theming (5 built-in themes)
- Mouse selection with OSC 52 clipboard
- Flexbox layout integration
- Keyboard-first with mouse support
Container for composing tui.Component instances with focus cycling.
app := tui.NewApplication()
app.AddComponent(tui.NewStatusBar())
app.AddComponent(tui.NewActivityBar())Two-pane layout with keyboard-driven focus and resize controls.
split := tui.NewSplitPane(
tui.WithLeftComponent(tui.NewFileExplorer(".")),
tui.WithRightComponent(tui.NewConversationView()),
)Planned standalone container; today, scrolling is built into components like ConversationView, FileExplorer, and ThreadProgress.
cv := tui.NewConversationView()
cv.AddMessage(tui.Message{Role: tui.RoleAssistant, Content: "Hello"})
cv.ScrollToBottom()Responsive metric grid for StatCard components with drill-down support.
d := tui.NewDashboard(
tui.WithDashboardTitle("System Metrics"),
tui.WithCards(tui.NewStatCard(tui.WithTitle("CPU"))),
)Helper for common github.com/SCKelemen/layout node patterns.
helper := tui.NewLayoutHelper()
root := helper.TwoColumnLayout(1, 2)
_ = rootMulti-column header with sections and alignment.
h := tui.NewHeader(tui.WithColumns(
tui.HeaderColumn{Align: tui.AlignLeft, Content: []string{"Project"}},
tui.HeaderColumn{Align: tui.AlignRight, Content: []string{"main"}},
))Compact metric card with value, trend, and change indicators.
card := tui.NewStatCard(
tui.WithTitle("Requests"),
tui.WithValue("12.4k"),
tui.WithChange(220, 1.8),
)Tree-like key/value renderer with status and spinner support.
sd := tui.NewStructuredData("Run")
sd.AddRow("Status", "Running").AddRow("Duration", "14s")
sd.MarkInfo()Static CLI table renderer (subpackage: tui/table).
tbl := table.New("Name", "Status")
tbl.AddRow("api", "ready")
fmt.Println(tbl.Render())Collapsible code view with optional mouse selection and copy.
cb := tui.NewCodeBlock(
tui.WithCodeFilename("main.go"),
tui.WithCode("package main\nfunc main() {}"),
)Unified diff renderer with expand/collapse and selection support.
db := tui.NewDiffBlockFromStrings("a\n", "a\nb\n",
tui.WithDiffFilename("notes.txt"),
tui.WithDiffSummary("Add one line"),
)Keyboard-driven tab strip with optional close behavior.
tabs := tui.NewTabBar(tui.WithTabs(
tui.Tab{ID: "one", Label: "Overview"},
tui.Tab{ID: "two", Label: "Logs"},
))Navigable path component with overflow truncation.
bc := tui.NewBreadcrumb(tui.WithBreadcrumbItems(
tui.BreadcrumbItem{ID: "root", Label: "workspace"},
tui.BreadcrumbItem{ID: "repo", Label: "tui"},
))Fuzzy-search command launcher for keyboard-first workflows.
cp := tui.NewCommandPalette([]tui.Command{{
Name: "Refresh", Category: "View", Action: func() tea.Cmd { return nil },
}})
cp.Show()Tree file browser with expand/collapse and hidden file toggle.
fe := tui.NewFileExplorer(".", tui.WithShowHidden(false))
_ = fe.GetSelectedPath()
fe.Focus()Multi-line textarea input with submit and clear shortcuts.
ti := tui.NewTextInput()
ti.OnSubmit(func(s string) tea.Cmd { return nil })
ti.Focus()Overlay dialog for alert, confirm, and input workflows.
m := tui.NewModal(tui.WithModalTitle("Confirm"))
m.ShowConfirm("Delete", "Delete file?", func() tea.Cmd { return nil }, nil)
m.Focus()Inline confirmation prompt with code preview and choice list.
confirm := tui.NewConfirmationBlock(
tui.WithConfirmDescription("Write config file"),
tui.WithConfirmOptions([]string{"Yes", "No"}),
)Interactive checklist with nested items and status icons.
cl := tui.NewChecklist(tui.WithChecklistItems(
tui.ChecklistItem{ID: "1", Label: "Run tests"},
tui.ChecklistItem{ID: "2", Label: "Update docs"},
))Animated status line with elapsed time and progress hint.
ab := tui.NewActivityBar()
ab.Start("Deploying…")
ab.SetProgress("step 2/4")Bottom status row for state and keybinding hints.
sb := tui.NewStatusBar()
sb.SetMessage("Ready")
sb.Focus()Stacked auto-dismiss notifications.
toast := tui.NewToast()
toast.PushSuccess("Saved")
toast.PushWarning("Low disk space")Collapsible tool output block with streaming status support.
tb := tui.NewToolBlock("Bash", "go test ./...", nil, tui.WithStreaming())
tb.AppendLine("ok ./pkg")
tb.SetStatus(tui.StatusComplete)Concurrent task/thread progress view with per-thread output.
tp := tui.NewThreadProgress()
tp.UpsertThread("lint", "Lint", tui.ThreadRunning)
tp.AppendOutput("lint", "running staticcheck")Scrollable transcript view with roles, timestamps, and streaming.
cv := tui.NewConversationView()
cv.AddMessage(tui.Message{Role: tui.RoleUser, Content: "Summarize tests"})
cv.AddMessage(tui.Message{Role: tui.RoleAssistant, Content: "All green"})Prebuilt animation frame sets for running states.
frame := tui.SpinnerDots.GetFrame(0)
count := tui.SpinnerThinking.FrameCount()
_, _ = frame, countStatus icon families for components that render state.
icons := tui.IconSetCodex
fmt.Println(icons.Success, icons.Error)Mouse-based text selection helper used by render components.
sm := tui.NewSelectionManager()
sm.SetOffset(0, 0)
_ = sm.HasSelection()Terminal clipboard support via OSC 52 escape sequences.
cmd := tui.WriteClipboard("copied from tui")
_ = cmd
_ = tui.WriteClipboardTarget("primary", tui.ClipboardPrimary)tui uses github.com/SCKelemen/design-system tokens. You can provide tokens directly or use named theme options where supported.
tokens := design.DefaultTheme()
midnight := design.MidnightTheme()
nord := design.NordTheme()
paper := design.PaperTheme()
wrapped := design.WrappedTheme()Example applying tokens to components:
status := tui.NewStatusBar(tui.WithStatusBarDesignTokens(tokens))
activity := tui.NewActivityBar(tui.WithActivityBarDesignTokens(midnight))
threads := tui.NewThreadProgress(tui.WithThreadProgressDesignTokens(nord))Example applying a named theme directly:
sd := tui.NewStructuredData("Plan", tui.WithStructuredDataTheme("paper"))
tool := tui.NewToolBlock("Read", "README.md", nil, tui.WithToolBlockTheme("wrapped"))
_ = sd
_ = toolMouse selection is available on text-heavy components and copies via OSC 52.
WithCodeBlockMouseSelection(true)WithDiffBlockMouseSelection(true)WithConversationMouseSelection(true)
When a selection exists:
Ctrl+Ccopies selected textycopies selected text when the component is focused- clipboard write uses
WriteClipboard/WriteClipboardTarget(OSC 52)
cb := tui.NewCodeBlock(
tui.WithCode("line1\nline2"),
tui.WithCodeBlockMouseSelection(true),
)
_ = cbSCKelemen stack dependencies in this module:
github.com/SCKelemen/cligithub.com/SCKelemen/colorgithub.com/SCKelemen/design-systemgithub.com/SCKelemen/layoutgithub.com/SCKelemen/text
Additional SCKelemen modules used indirectly:
github.com/SCKelemen/unicodegithub.com/SCKelemen/units
Bearware 1.0