Skip to content
Open source · MIT · Go 1.25+

Build terminal apps in Go

tui is a terminal UI framework built on the Elm Architecture. Standard library only, with 40+ widgets, flex and grid layout, a cell-diff renderer and a headless test harness.

go get github.com/ows4444/tui
┌────────────────────────────────────────────────────────────────────────┐
│                                                                        │
│ Service Dashboard                                               v2.1.0 │
│ ─────────────────────────────── status ─────────────────────────────── │
│                                                                        │
│ ✓ API           ✓ healthy      ✓ Build → ● Test → ○ Deploy             │
│ ⚠ Worker Queue  ⚠ degraded     ⠋ Deploying build  █████░░░░░░░░░░      │
│ ✗ Database      ✗ down                                                 │
│                                                                        │
│ ────────────────────────────── metrics ─────────────────────────────── │
│                                                                        │
│ CPU  ▅▆▄▁▁▄▂▃▃▆▂▅▃▆▇▅▂█▅▆  69.2%                                       │
│ Mem  █▄▆▂▃▇▄▄▃▂▄▇▃▂▆▁▅▁▁▃  30.2%                                       │
│ Disk ███░░░░░░░░░░░░       17.3%                                       │
│                                                                        │
│ ────────────────────────────────────────────────────────────────────── │
│ [r] refresh  [d] about  [q] quit                                       │
│                                                                        │
└────────────────────────────────────────────────────────────────────────┘
  • 0module dependencies
  • 40+widget packages
  • 30runnable examples
  • 7supported OSes

Why tui

Everything a terminal app needs, nothing it doesn’t

One module, the Go standard library, and conventions enforced by tests.

  • The Elm Architecture

    A Model has Init, Update and View. Update returns Cmds for side effects; the Program runs them and feeds the results back as Msgs.

  • Standard library only

    go.mod has no require directive, and a test in internal/archtest fails if any package imports outside the standard library.

  • Cell-diff rendering

    Each frame is parsed into a grid of cells and only the cells that changed are written, with relative cursor movement.

  • Widgets that compose

    Inputs, tables, trees, dialogs, menus, pickers, charts and more. Every widget has a LayoutNode() adapter and an accessible Linearize form.

  • Layout and theming

    Flex, grid and overlay layout nodes. 16 preset themes, component tokens, and glyph sets with an ASCII fallback.

  • Accessible output

    WithAccessible switches to append-only, unstyled output for screen readers; reduced motion follows NO_ANIMATION and REDUCE_MOTION.

  • Terminal-aware

    Colour depth from the environment (honours NO_COLOR), an opt-in capability probe, bracketed paste, mouse and kitty keyboard support.

  • Testable

    The tuitest harness drives a Program headlessly. Every example checks its screens against golden files: the screens on this site.

How it works

Three methods and a Program

  1. Model holds your state. Any value with Init, Update and View is one.
  2. Update gets every key, mouse event and resize as a Msg, and returns the next Model plus any Cmd to run.
  3. View returns a string. The Program diffs it cell by cell and writes only what changed.
  4. Run takes over the terminal and restores it on every way out.

This is ExampleNewProgram from example_test.go, which go test runs. Running a Program →

counter.go
type counter struct{ n int }
func (c counter) Init() tui.Cmd { return nil }
func (c counter) Update(msg tui.Msg) (tui.Model, tui.Cmd) {
if k, ok := msg.(tui.Key); ok && k.Type == tui.KeyRunes {
switch k.Text {
case "+":
c.n++
case "q":
return c, tui.Quit()
}
}
return c, nil
}
func (c counter) View() string { return fmt.Sprintf("count: %d", c.n) }
func main() {
if _, err := tui.NewProgram(counter{}).Run(); err != nil {
fmt.Println(err)
}
}

Built with tui

Real screens, not mock-ups

Each is the first frame an example’s own test checks, at 80×24.

All 30 example programs →

Learn

Start where you are

FAQ

Frequently asked questions

What is tui?

tui is a terminal UI (TUI) framework for Go, at github.com/ows4444/tui. An application is a Model with Init, Update and View (the Elm Architecture); tui.NewProgram runs it, reads keys, mouse events and resizes, and redraws View with a cell diff so only changed cells are written.

How do I install tui?

Run go get github.com/ows4444/tui. It needs Go 1.25 or later. There is no tagged release yet, so this resolves to a pseudo-version of the latest commit.

Does tui have any dependencies?

No. tui uses only the Go standard library: go.mod has no require directive, and a test in internal/archtest fails if any package imports outside the standard library and the module.

Which platforms does tui support?

Linux, macOS, Windows, FreeBSD, OpenBSD, NetBSD and DragonFly BSD. CI runs the tests on Linux, macOS, Windows and FreeBSD; OpenBSD, NetBSD and DragonFly BSD are cross-compiled. Other operating systems, including Solaris and illumos, fail to build on purpose.

Does tui work with screen readers?

tui.WithAccessible(true) switches a Program to an append-only, unstyled plain-text transcript that a screen reader can follow, and WithAccessibleAuto turns it on for ACCESSIBLE=1 or TERM=dumb. No run with VoiceOver, NVDA or Orca is recorded yet, so screen-reader support is unverified. See Accessibility.

How do I test a tui application?

The tuitest package runs a model in a real tui.Program against an in-memory terminal: keys, pastes, resizes and messages go in, and the emulated screen comes out as lines that can be compared against golden files. See Testing.

What license is tui under?

MIT.

Ready to build?

Install the module and have a running program in a few minutes.