An open API service indexing awesome lists of open source software.

https://github.com/grindlemire/go-tui

A declarative terminal UI framework for Go.
https://github.com/grindlemire/go-tui

golang tui

Last synced: about 2 months ago
JSON representation

A declarative terminal UI framework for Go.

Awesome Lists containing this project

README

          





go-tui


Reactive Terminal UIs in Go


Go Reference
CI
License
Go Report Card


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

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

## Quick look

**counter.gsx**

```go
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() {


{fmt.Sprintf("Count: %d", c.count.Get())}
+/- to change, q to quit

}
```

**main.go**

```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)
}
}
```

```bash
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/`](examples/) directory has runnable programs for each feature area. Examples 01 through 23 accompany the [guides](https://go-tui.dev).

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

See also [`ai-chat`](examples/ai-chat) and [`docs-example`](examples/docs-example).

```bash
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/`](editor/vscode/). Syntax highlighting, completion, hover, go-to-definition, diagnostics, and formatting.

**Neovim**: Install the plugin from [`editor/nvim/`](editor/nvim/). Syntax highlighting via tree-sitter, LSP integration, and filetype detection. See the [Neovim README](editor/nvim/README.md) for setup instructions.

**Helix**: Tree-sitter grammar at [`editor/tree-sitter-gsx/`](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](https://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