Hex1b

September 2, 2026 ยท View on GitHub

Hex1b is a .NET library for building rich, interactive terminal user interfaces (TUI) with a React-inspired declarative API. Create beautiful console applications with widgets, layouts, theming, and more.

.NET License

โœจ Features

  • Declarative UI - Build UIs using a widget tree pattern inspired by React and Flutter
  • Widget Library - TextBlock, TextBox, Button, List, VStack, HStack, Splitter, and more
  • Layout System - Flexible constraint-based layout with size hints (Fill, Content, Fixed)
  • Theming - Built-in themes with customizable colors and styles
  • Input Handling - Keyboard navigation, focus management, and shortcut bindings
  • Reconciliation - Efficient diff-based updates to minimize terminal redraws

๐Ÿ“ฆ Installation

dotnet add package Hex1b

๐Ÿš€ Quick Start

Here's a simple "Hello World" application:

using Hex1b;
using Hex1b.Widgets;

using var cts = new CancellationTokenSource();
Console.CancelKeyPress += (_, e) => { e.Cancel = true; cts.Cancel(); };

using var app = new Hex1bApp(
    ctx => Task.FromResult<Hex1bWidget>(
        new VStackWidget([
            new TextBlockWidget("Hello, Terminal!"),
            new ButtonWidget("Exit", () => cts.Cancel())
        ])
    )
);

await app.RunAsync(cts.Token);

๐ŸŽจ Widgets

Hex1b provides a variety of built-in widgets:

WidgetDescription
TextBlockWidgetDisplay static or dynamic text
TextBoxWidgetEditable text input with cursor and selection
ButtonWidgetClickable button with label and action
ListWidgetScrollable list with selection
VStackWidgetVertical layout container
HStackWidgetHorizontal layout container
SplitterWidgetResizable split pane layout

๐Ÿ“ Layout System

Hex1b uses a constraint-based layout system with size hints:

// Children with size hints: first fills available space, second sizes to content
new VStackWidget(
    [contentWidget, statusBarWidget],
    [SizeHint.Fill, SizeHint.Content]
);

Size Hints:

  • SizeHint.Fill - Expand to fill available space
  • SizeHint.Content - Size to fit content
  • SizeHint.Fixed(n) - Fixed size of n units

๐ŸŽน Input Bindings

Define keyboard bindings at any level of your widget tree:

var widget = new SplitterWidget(left, right, 25) with
{
    InputBindings = [
        InputBinding.Ctrl(Hex1bKey.S, Save, "Save"),
        InputBinding.Ctrl(Hex1bKey.Q, Quit, "Quit"),
    ]
};

Picking portable bindings. Different terminals intercept different combos before they reach Hex1b (e.g. Windows Terminal eats Ctrl+Shift+โ†‘/โ†“ for scroll, GNOME Terminal eats Ctrl+Shift+T/N/W for tab/window management). See Keybinding Portability on hex1b.dev for the per-terminal interception matrix and recommendations, and use the KeyBindingTester sample to confirm what actually fires on your target terminals.

๐ŸŽจ Theming

Apply built-in themes or create your own:

using var app = new Hex1bApp(builder, new Hex1bAppOptions { Theme = Hex1bThemes.Sunset });

๐Ÿ—๏ธ Architecture

Hex1b follows a widget/node separation pattern:

  1. Widgets - Immutable configuration objects describing what to render
  2. Nodes - Mutable render objects that manage state and layout
  3. Reconciliation - Efficient diffing to update nodes when widgets change
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                      Hex1bApp.RunAsync()                    โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚  1. Build widget tree (your code)                           โ”‚
โ”‚  2. Reconcile โ†’ Update node tree                            โ”‚
โ”‚  3. Layout โ†’ Measure and arrange nodes                      โ”‚
โ”‚  4. Render โ†’ Draw to terminal                               โ”‚
โ”‚  5. Wait for input โ†’ Dispatch to focused node               โ”‚
โ”‚  6. Repeat from step 1                                      โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

๐Ÿงช Samples

The samples/ directory contains example applications demonstrating various features:

  • Cancellation - Master-detail contact editor with save/cancel functionality
  • RemoteTerminalAuthDemo - Connects a client to a bearer-protected remote terminal server

Running Samples with Aspire

This repository is set up with Aspire to make it easy to run and test sample applications:

dotnet run --project apphost.cs

Note: Aspire doesn't natively support interactive terminal applications, but this project explores techniques to make TUI app development and testing in Aspire possible.

๐Ÿ› ๏ธ Development

Prerequisites

  • .NET 10.0 SDK (preview)
  • A terminal emulator with good ANSI support

Building

dotnet build

Running Tests

dotnet test

Project Structure

hex1b/
โ”œโ”€โ”€ src/
โ”‚   โ””โ”€โ”€ Hex1b/              # Main library
โ”‚       โ”œโ”€โ”€ Layout/         # Constraint-based layout system
โ”‚       โ”œโ”€โ”€ Nodes/          # Render nodes (mutable, stateful)
โ”‚       โ”œโ”€โ”€ Widgets/        # Widget definitions (immutable config)
โ”‚       โ”œโ”€โ”€ Theming/        # Theme system and built-in themes
โ”‚       โ””โ”€โ”€ Input/          # Keyboard input and bindings
โ”œโ”€โ”€ samples/                # Example applications
โ”œโ”€โ”€ docs/                   # Architecture & reference documentation
โ”œโ”€โ”€ tests/
โ”‚   โ””โ”€โ”€ Hex1b.Tests/        # Unit tests
โ””โ”€โ”€ apphost.cs              # Aspire app host for running samples

๐Ÿ“š Documentation

Full documentation lives at hex1b.dev. Highlights:

  • Input Handling โ€” focus, routing, declarative bindings, and Vim/Emacs-style remap walkthrough.
  • Keybinding Portability โ€” per-terminal interception matrix (Windows Terminal, ConPTY, macOS Terminal.app, iTerm2, Ghostty, kitty, GNOME Terminal, Ptyxis, xterm, tmux, ssh) plus cross-cutting ANSI protocol limits.
  • Terminal Emulator โ€” using the embedded terminal widget.
  • API Reference โ€” generated namespace docs.

In-repo design / architecture notes (not on the website):

For the manual portability harness used to generate the per-terminal data, see samples/KeyBindingTester.

๐Ÿค Contributing

Contributions are welcome! Please see CONTRIBUTING.md for guidelines.

For AI coding agents, see AGENTS.md for context and conventions.

๐Ÿ“„ License

This project is licensed under the MIT License - see the LICENSE file for details.