gitstack

grindlemire/go-tui code browser

203 entries
name size
.github/ - cmd/ - docs/ - editor/ - examples/ - internal/ - scripts/ - .gitignore 1022 B .golangci.yml 587 B .goreleaser.yaml 896 B .release-please-manifest.json 20 B AGENTS.md 326 B CHANGELOG.md 51.5 KB CLAUDE.md 39.0 KB LICENSE 1.0 KB README.md 8.4 KB app.go 17.9 KB app_construct_test.go 4.9 KB app_events.go 3.1 KB app_events_test.go 5.6 KB app_inline_startup.go 2.7 KB app_inline_test.go 35.6 KB app_input_reporting.go 1.5 KB app_input_reporting_test.go 1.6 KB app_integration_test.go 10.7 KB app_lifecycle.go 10.6 KB app_lifecycle_test.go 5.6 KB app_loop.go 4.9 KB app_manual_test.go 7.1 KB app_options.go 6.2 KB app_options_test.go 9.4 KB app_overlay.go 1.3 KB app_render.go 6.9 KB app_render_test.go 9.3 KB app_resize_test.go 7.0 KB app_resize_unix.go 821 B app_resize_windows.go 392 B app_screen.go 2.5 KB app_screen_test.go 10.5 KB app_suspend_test.go 13.4 KB app_suspend_unix.go 5.5 KB app_suspend_windows.go 474 B app_test.go 3.8 KB border.go 12.2 KB border_test.go 14.0 KB buffer.go 15.5 KB buffer_diff_test.go 4.4 KB buffer_test.go 12.5 KB buffer_text_test.go 7.9 KB caps.go 4.1 KB caps_test.go 10.0 KB cell.go 4.7 KB cell_test.go 9.1 KB click.go 1014 B click_test.go 3.4 KB codecov.yml 371 B color.go 9.2 KB color_test.go 13.8 KB component.go 2.0 KB component_test.go 366 B design.md 17.3 KB dirty.go 415 B dirty_test.go 2.3 KB dispatch.go 5.7 KB dispatch_focus_test.go 3.9 KB dispatch_test.go 26.4 KB doc.go 230 B element.go 4.3 KB element_accessors.go 4.2 KB element_accessors_test.go 5.4 KB element_focus.go 6.5 KB element_focus_test.go 4.1 KB element_integration_render_test.go 11.8 KB element_integration_test.go 7.9 KB element_layout.go 9.3 KB element_layout_test.go 12.7 KB element_options.go 11.8 KB element_options_auto.go 302 B element_options_test.go 7.8 KB element_render.go 18.7 KB element_render_hr_test.go 3.9 KB element_render_test.go 25.6 KB element_scroll.go 7.1 KB element_scroll_test.go 4.4 KB element_scrollbox_test.go 7.1 KB element_test.go 11.4 KB element_tree.go 2.0 KB element_tree_test.go 3.3 KB element_watchers.go 2.5 KB element_watchers_test.go 1.5 KB escape.go 11.1 KB escape_sequences_test.go 2.2 KB escape_style_test.go 6.7 KB escape_test.go 6.7 KB event.go 3.3 KB event_app_test.go 1.0 KB event_test.go 4.6 KB events.go 4.7 KB events_test.go 9.1 KB focus.go 9.7 KB focus_dispatch_test.go 4.8 KB focus_group.go 2.5 KB focus_group_test.go 6.7 KB focus_integration_test.go 4.9 KB focus_test.go 11.1 KB generate.go 411 B go.mod 205 B go.sum 785 B highlight.go 3.3 KB highlight_test.go 1.2 KB inline_ansi.go 1.0 KB inline_scan.go 2.6 KB inline_scan_test.go 2.2 KB inline_session.go 11.0 KB inline_session_test.go 4.5 KB inline_stream.go 1.5 KB inline_stream_test.go 1.9 KB inline_wrap.go 4.3 KB input.go 10.0 KB input_options.go 2.6 KB input_options_test.go 5.3 KB input_test.go 24.8 KB integration_event_test.go 8.2 KB integration_test.go 9.9 KB key.go 6.8 KB key_spec_test.go 4.8 KB key_test.go 3.8 KB keymap.go 2.2 KB keymap_test.go 11.2 KB layout.go 4.8 KB layout_helpers_test.go 2.0 KB markdown.go 13.4 KB markdown_codefence_mismatch_test.go 1.0 KB markdown_codefence_test.go 1.5 KB markdown_options.go 1.2 KB markdown_test.go 12.2 KB markdown_theme.go 2.7 KB markdown_theme_test.go 1.5 KB mock_reader.go 1.6 KB mock_terminal.go 7.8 KB modal.go 5.2 KB modal_options.go 1.9 KB modal_test.go 13.8 KB mount.go 5.6 KB mount_key.go 939 B mount_key_test.go 2.0 KB mount_layout_test.go 13.7 KB mount_test.go 15.7 KB overlay_test.go 1.3 KB parse.go 12.2 KB parse_mouse_test.go 5.4 KB parse_test.go 22.1 KB print.go 1.7 KB print_test.go 3.1 KB reader.go 8.3 KB reader_pause_test.go 7.6 KB reader_resize_test.go 1.4 KB reader_test.go 11.4 KB reader_types.go 1.4 KB reader_unix.go 2.1 KB reader_windows.go 11.1 KB rect_ops_test.go 7.1 KB rect_test.go 5.2 KB ref.go 3.0 KB ref_test.go 6.5 KB release-please-config.json 171 B render.go 1.5 KB render_element.go 2.3 KB render_element_test.go 4.3 KB render_trailing_test.go 2.2 KB richtext.go 2.0 KB richtext_test.go 2.1 KB state.go 8.5 KB state_batch_test.go 7.5 KB state_binding_test.go 7.8 KB state_test.go 5.0 KB stream_writer.go 3.3 KB stream_writer_test.go 6.0 KB style.go 2.4 KB style_test.go 6.5 KB table_render_test.go 2.2 KB terminal.go 4.1 KB terminal_ansi.go 10.3 KB terminal_ansi_kitty_unix.go 2.4 KB terminal_ansi_kitty_windows.go 223 B terminal_ansi_test.go 2.5 KB terminal_emulator_test.go 12.3 KB terminal_sysv.go 1.5 KB terminal_test.go 10.2 KB terminal_unix.go 2.2 KB terminal_windows.go 1.7 KB test_main_test.go 452 B text_wrap.go 5.2 KB text_wrap_layout_test.go 4.2 KB text_wrap_test.go 9.3 KB textarea.go 15.1 KB textarea_options.go 3.4 KB textarea_options_test.go 7.3 KB textarea_test.go 11.4 KB watcher.go 3.4 KB watcher_collect.go 419 B watcher_collect_test.go 2.4 KB watcher_test.go 11.0 KB
README.md 8.4 KB

go-tui

Reactive Terminal UIs in Go

Go Reference CI License Go Report Card Coverage

Define terminal interfaces in .gsx templates with HTML-like syntax and Tailwind-style classes.
The compiler generates type-safe Go. The runtime handles flexbox layout, reactive state, and rendering.

Guides & API Reference · Examples · Editor Support

Pre-1.0: go-tui is under active development. Some APIs may evolve as the project matures.


Install

go get github.com/grindlemire/go-tui
go install github.com/grindlemire/go-tui/cmd/tui@latest

Quick look

counter.gsx

package main

import (
    "fmt"
    tui "github.com/grindlemire/go-tui"
)

type counter struct {
    count *tui.State[int]
}

func Counter() *counter {
    return &counter{count: tui.NewState(0)}
}

func (c *counter) KeyMap() tui.KeyMap {
    return tui.KeyMap{
        tui.On(tui.Rune('+'), func(ke tui.KeyEvent) { c.count.Update(func(v int) int { return v + 1 }) }),
        tui.On(tui.Rune('-'), func(ke tui.KeyEvent) { c.count.Update(func(v int) int { return v - 1 }) }),
        tui.On(tui.Rune('q'), func(ke tui.KeyEvent) { ke.App().Stop() }),
    }
}

templ (c *counter) Render() {
    <div class="flex-col items-center justify-center h-full gap-1">
        <span class="font-bold text-cyan">{fmt.Sprintf("Count: %d", c.count.Get())}</span>
        <span class="font-dim">+/- to change, q to quit</span>
    </div>
}

main.go

package main

import (
    "fmt"
    "os"
    tui "github.com/grindlemire/go-tui"
)

func main() {
    app, err := tui.NewApp(tui.WithRootComponent(Counter()))
    if err != nil {
        fmt.Fprintf(os.Stderr, "%v\n", err)
        os.Exit(1)
    }
    defer app.Close()
    if err := app.Run(); err != nil {
        fmt.Fprintf(os.Stderr, "%v\n", err)
        os.Exit(1)
    }
}
tui generate counter.gsx
go run .

The generate command compiles .gsx files into plain Go source (*_gsx.go) that you can read, debug, and commit.

What's in the box

  • .gsx templates with HTML-like elements and Tailwind-style utility classes, compiled to type-safe Go
  • Pure Go flexbox layout without CGO: row, column, justify, align, gap, padding, margin, percentage widths, min/max constraints
  • Generic State[T] with automatic re-rendering, batched updates, and bindings
  • Struct components with keyboard/mouse handlers, watchers for timers and channels, refs, and a {children...} slot
  • Modal dialogs with backdrop, focus trapping, and preemptive key handling
  • Language server, formatter, and tree-sitter grammar for VS Code
  • Only depends on golang.org/x/{sys,tools}, pure Go from terminal to layout

How it works

.gsx files
    │  tui generate
Go source (*_gsx.go)
    │  go build
Widget tree + flexbox layout engine
Double-buffered character grid
    │  diff-based updates
Terminal (ANSI escape sequences)

The .gsx compiler runs at build time and produces regular Go files. At runtime, the program builds a tree of *tui.Element nodes. The layout engine positions them with flexbox, and a double-buffered renderer diffs the output to minimize terminal writes.

Examples

The examples/ directory has runnable programs for each feature area. Examples 01 through 23 accompany the guides.

Example What it covers
01-getting-started Minimal component, gradient text, quit handling
02-gsx-syntax GSX file structure, templ syntax, control flow
03-styling Colors, text styles, borders, conditional styling
04-layout Flexbox row/column, justify, align, reusable layouts
05-elements Built-in elements, disabled state, progress bars
06-state State[T], if/for/:= bindings, reactive children, modal dialog
07-components Component composition, tabs, {children...} slot
08-events Keyboard event handling, KeyMap, OnKey/OnRune
09-refs-and-clicks Refs, click handling, mouse + keyboard, modal with onActivate
10-scrolling Scrollable containers, keyboard navigation
11-focus Focus management, tab cycling
12-watchers Interval timers, channel watchers, live data
13-testing Unit testing components
14-multi-component Multi-file components, shared state
15-inline-mode Inline terminal rendering mode
16-streaming Auto-scroll, stick-to-bottom, streaming data
17-inline-streaming Inline mode with streaming content
18-dashboard Metrics, sparklines, scrollable event log
19-print One-shot rendering, print and exit
20-animation Frame-cycling spinners, eased progress, color wave, pulsing border
21-directory-tree Foldable directory tree, lazy loading, scroll-to-cursor, path highlighting
22-event-loop Custom event loops via Open, Step, Events, Dispatch, Render
23-event-dump Diagnostic event log for verifying key, mouse, and resize handling

See also ai-chat and docs-example.

cd examples/01-getting-started && go run .

CLI

tui generate [path...]       Compile .gsx files to Go source
tui check [path...]          Validate without generating
tui fmt [path...]            Format .gsx files in place
tui fmt --check [path...]    Check formatting without modifying
tui lsp                      Start the language server (stdio)
tui version                  Print version

tui generate ./... compiles all .gsx files under the current directory.

Editor support

VS Code: Install the extension from editor/vscode/. Syntax highlighting, completion, hover, go-to-definition, diagnostics, and formatting.

Neovim: Install the plugin from editor/nvim/. Syntax highlighting via tree-sitter, LSP integration, and filetype detection. See the Neovim README for setup instructions.

Helix: Tree-sitter grammar at editor/tree-sitter-gsx/.

The tui lsp language server works with any editor that speaks JSON-RPC over stdio. It proxies Go-specific features through gopls with .gsx to .go source mapping.

Documentation

Guides, syntax reference, and API docs: go-tui.dev

Why are there so many files?

I wanted the imports to all be at the root so there is only a single package for the user to import and worry about (rather than an elements, styles, layout, etc.). Go Unfortunately doesn't have any indirection semantics for imports so I had to put a bunch of files in the root.

License

MIT