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

https://github.com/mitchdenny/hex1b

The .NET Terminal Application Stack
https://github.com/mitchdenny/hex1b

csharp dotnet react terminal tui tui-app

Last synced: 19 days ago
JSON representation

The .NET Terminal Application Stack

Awesome Lists containing this project

README

          

# Hex1b

**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](https://img.shields.io/badge/.NET-10.0-512BD4)](https://dotnet.microsoft.com/)
[![License](https://img.shields.io/badge/license-MIT-blue.svg)](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

```bash
dotnet add package Hex1b
```

## ๐Ÿš€ Quick Start

Here's a simple "Hello World" application:

```csharp
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(
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:

| Widget | Description |
|--------|-------------|
| `TextBlockWidget` | Display static or dynamic text |
| `TextBoxWidget` | Editable text input with cursor and selection |
| `ButtonWidget` | Clickable button with label and action |
| `ListWidget` | Scrollable list with selection |
| `VStackWidget` | Vertical layout container |
| `HStackWidget` | Horizontal layout container |
| `SplitterWidget` | Resizable split pane layout |

## ๐Ÿ“ Layout System

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

```csharp
// 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:

```csharp
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](https://hex1b.dev/guide/keybinding-portability)
> on hex1b.dev for the per-terminal interception matrix and recommendations,
> and use the [`KeyBindingTester`](./samples/KeyBindingTester/README.md)
> sample to confirm what actually fires on your target terminals.

## ๐ŸŽจ Theming

Apply built-in themes or create your own:

```csharp
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

### Running Samples with Aspire

This repository is set up with [Aspire](https://aspire.dev/) to make it easy to run and test sample applications:

```bash
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](https://dotnet.microsoft.com/download) (preview)
- A terminal emulator with good ANSI support

### Building

```bash
dotnet build
```

### Running Tests

```bash
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](https://hex1b.dev)**. Highlights:

- [Input Handling](https://hex1b.dev/guide/input) โ€” focus, routing, declarative
bindings, and Vim/Emacs-style remap walkthrough.
- [Keybinding Portability](https://hex1b.dev/guide/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](https://hex1b.dev/guide/terminal-emulator) โ€” using the
embedded terminal widget.
- [API Reference](https://hex1b.dev/reference/) โ€” generated namespace docs.

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

- [`docs/terminal.md`](./docs/terminal.md) โ€” Presentation/workload adapter
architecture.
- [`docs/child-process-arch.md`](./docs/child-process-arch.md) โ€” Child
process / PTY architecture.
- [`docs/muxer-protocol.md`](./docs/muxer-protocol.md) โ€” Muxer wire protocol.

For the manual portability harness used to generate the per-terminal data,
see [`samples/KeyBindingTester`](./samples/KeyBindingTester/README.md).

## ๐Ÿค Contributing

Contributions are welcome! Please see [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.

For AI coding agents, see [AGENTS.md](AGENTS.md) for context and conventions.

## ๐Ÿ“„ License

This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.

## ๐Ÿ”— Related Projects

- [Spectre.Console](https://spectreconsole.net/) - Beautiful console output
- [Terminal.Gui](https://github.com/gui-cs/Terminal.Gui) - Cross-platform terminal UI toolkit
- [Aspire](https://aspire.dev/) - Cloud-ready stack for .NET