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.
- 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
dotnet add package Hex1bHere'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);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 |
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 spaceSizeHint.Content- Size to fit contentSizeHint.Fixed(n)- Fixed size of n units
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 eatsCtrl+Shift+T/N/Wfor tab/window management). See Keybinding Portability on hex1b.dev for the per-terminal interception matrix and recommendations, and use theKeyBindingTestersample to confirm what actually fires on your target terminals.
Apply built-in themes or create your own:
using var app = new Hex1bApp(builder, new Hex1bAppOptions { Theme = Hex1bThemes.Sunset });Hex1b follows a widget/node separation pattern:
- Widgets - Immutable configuration objects describing what to render
- Nodes - Mutable render objects that manage state and layout
- 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 β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
The samples/ directory contains example applications demonstrating various features:
- Cancellation - Master-detail contact editor with save/cancel functionality
This repository is set up with Aspire to make it easy to run and test sample applications:
dotnet run --project apphost.csNote: Aspire doesn't natively support interactive terminal applications, but this project explores techniques to make TUI app development and testing in Aspire possible.
- .NET 10.0 SDK (preview)
- A terminal emulator with good ANSI support
dotnet builddotnet testhex1b/
βββ 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
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):
docs/terminal.mdβ Presentation/workload adapter architecture.docs/child-process-arch.mdβ Child process / PTY architecture.docs/muxer-protocol.mdβ Muxer wire protocol.
For the manual portability harness used to generate the per-terminal data,
see samples/KeyBindingTester.
Contributions are welcome! Please see CONTRIBUTING.md for guidelines.
For AI coding agents, see AGENTS.md for context and conventions.
This project is licensed under the MIT License - see the LICENSE file for details.
- Spectre.Console - Beautiful console output
- Terminal.Gui - Cross-platform terminal UI toolkit
- Aspire - Cloud-ready stack for .NET