{"id":34901303,"url":"https://github.com/mitchdenny/hex1b","last_synced_at":"2026-05-24T12:03:40.803Z","repository":{"id":327879277,"uuid":"1111094078","full_name":"mitchdenny/hex1b","owner":"mitchdenny","description":"The .NET Terminal Application Stack","archived":false,"fork":false,"pushed_at":"2026-05-24T03:18:52.000Z","size":15013,"stargazers_count":158,"open_issues_count":56,"forks_count":14,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-24T05:09:47.476Z","etag":null,"topics":["csharp","dotnet","react","terminal","tui","tui-app"],"latest_commit_sha":null,"homepage":"https://hex1b.dev","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mitchdenny.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null}},"created_at":"2025-12-06T08:59:39.000Z","updated_at":"2026-05-24T03:09:03.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/mitchdenny/hex1b","commit_stats":null,"previous_names":["mitchdenny/custard"],"tags_count":158,"template":false,"template_full_name":null,"purl":"pkg:github/mitchdenny/hex1b","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mitchdenny%2Fhex1b","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mitchdenny%2Fhex1b/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mitchdenny%2Fhex1b/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mitchdenny%2Fhex1b/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mitchdenny","download_url":"https://codeload.github.com/mitchdenny/hex1b/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mitchdenny%2Fhex1b/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33432867,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-23T22:14:44.296Z","status":"online","status_checked_at":"2026-05-24T02:00:06.296Z","response_time":57,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["csharp","dotnet","react","terminal","tui","tui-app"],"created_at":"2025-12-26T08:53:57.834Z","updated_at":"2026-05-24T12:03:40.767Z","avatar_url":"https://github.com/mitchdenny.png","language":"C#","funding_links":[],"categories":["Table of Contents"],"sub_categories":[],"readme":"# Hex1b\n\n**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.\n\n[![.NET](https://img.shields.io/badge/.NET-10.0-512BD4)](https://dotnet.microsoft.com/)\n[![License](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)\n\n## ✨ Features\n\n- **Declarative UI** - Build UIs using a widget tree pattern inspired by React and Flutter\n- **Widget Library** - TextBlock, TextBox, Button, List, VStack, HStack, Splitter, and more\n- **Layout System** - Flexible constraint-based layout with size hints (Fill, Content, Fixed)\n- **Theming** - Built-in themes with customizable colors and styles\n- **Input Handling** - Keyboard navigation, focus management, and shortcut bindings\n- **Reconciliation** - Efficient diff-based updates to minimize terminal redraws\n\n## 📦 Installation\n\n```bash\ndotnet add package Hex1b\n```\n\n## 🚀 Quick Start\n\nHere's a simple \"Hello World\" application:\n\n```csharp\nusing Hex1b;\nusing Hex1b.Widgets;\n\nusing var cts = new CancellationTokenSource();\nConsole.CancelKeyPress += (_, e) =\u003e { e.Cancel = true; cts.Cancel(); };\n\nusing var app = new Hex1bApp(\n    ctx =\u003e Task.FromResult\u003cHex1bWidget\u003e(\n        new VStackWidget([\n            new TextBlockWidget(\"Hello, Terminal!\"),\n            new ButtonWidget(\"Exit\", () =\u003e cts.Cancel())\n        ])\n    )\n);\n\nawait app.RunAsync(cts.Token);\n```\n\n## 🎨 Widgets\n\nHex1b provides a variety of built-in widgets:\n\n| Widget | Description |\n|--------|-------------|\n| `TextBlockWidget` | Display static or dynamic text |\n| `TextBoxWidget` | Editable text input with cursor and selection |\n| `ButtonWidget` | Clickable button with label and action |\n| `ListWidget` | Scrollable list with selection |\n| `VStackWidget` | Vertical layout container |\n| `HStackWidget` | Horizontal layout container |\n| `SplitterWidget` | Resizable split pane layout |\n\n## 📐 Layout System\n\nHex1b uses a constraint-based layout system with size hints:\n\n```csharp\n// Children with size hints: first fills available space, second sizes to content\nnew VStackWidget(\n    [contentWidget, statusBarWidget],\n    [SizeHint.Fill, SizeHint.Content]\n);\n```\n\n**Size Hints:**\n- `SizeHint.Fill` - Expand to fill available space\n- `SizeHint.Content` - Size to fit content\n- `SizeHint.Fixed(n)` - Fixed size of n units\n\n## 🎹 Input Bindings\n\nDefine keyboard bindings at any level of your widget tree:\n\n```csharp\nvar widget = new SplitterWidget(left, right, 25) with\n{\n    InputBindings = [\n        InputBinding.Ctrl(Hex1bKey.S, Save, \"Save\"),\n        InputBinding.Ctrl(Hex1bKey.Q, Quit, \"Quit\"),\n    ]\n};\n```\n\n\u003e **Picking portable bindings.** Different terminals intercept different\n\u003e combos before they reach Hex1b (e.g. Windows Terminal eats `Ctrl+Shift+↑/↓`\n\u003e for scroll, GNOME Terminal eats `Ctrl+Shift+T/N/W` for tab/window\n\u003e management). See [Keybinding Portability](https://hex1b.dev/guide/keybinding-portability)\n\u003e on hex1b.dev for the per-terminal interception matrix and recommendations,\n\u003e and use the [`KeyBindingTester`](./samples/KeyBindingTester/README.md)\n\u003e sample to confirm what actually fires on your target terminals.\n\n## 🎨 Theming\n\nApply built-in themes or create your own:\n\n```csharp\nusing var app = new Hex1bApp(builder, new Hex1bAppOptions { Theme = Hex1bThemes.Sunset });\n```\n\n## 🏗️ Architecture\n\nHex1b follows a widget/node separation pattern:\n\n1. **Widgets** - Immutable configuration objects describing what to render\n2. **Nodes** - Mutable render objects that manage state and layout\n3. **Reconciliation** - Efficient diffing to update nodes when widgets change\n\n```\n┌─────────────────────────────────────────────────────────────┐\n│                      Hex1bApp.RunAsync()                    │\n├─────────────────────────────────────────────────────────────┤\n│  1. Build widget tree (your code)                           │\n│  2. Reconcile → Update node tree                            │\n│  3. Layout → Measure and arrange nodes                      │\n│  4. Render → Draw to terminal                               │\n│  5. Wait for input → Dispatch to focused node               │\n│  6. Repeat from step 1                                      │\n└─────────────────────────────────────────────────────────────┘\n```\n\n## 🧪 Samples\n\nThe `samples/` directory contains example applications demonstrating various features:\n\n- **Cancellation** - Master-detail contact editor with save/cancel functionality\n\n### Running Samples with Aspire\n\nThis repository is set up with [Aspire](https://aspire.dev/) to make it easy to run and test sample applications:\n\n```bash\ndotnet run --project apphost.cs\n```\n\n\u003e **Note**: Aspire doesn't natively support interactive terminal applications, but this project explores techniques to make TUI app development and testing in Aspire possible.\n\n## 🛠️ Development\n\n### Prerequisites\n\n- [.NET 10.0 SDK](https://dotnet.microsoft.com/download) (preview)\n- A terminal emulator with good ANSI support\n\n### Building\n\n```bash\ndotnet build\n```\n\n### Running Tests\n\n```bash\ndotnet test\n```\n\n### Project Structure\n\n```\nhex1b/\n├── src/\n│   └── Hex1b/              # Main library\n│       ├── Layout/         # Constraint-based layout system\n│       ├── Nodes/          # Render nodes (mutable, stateful)\n│       ├── Widgets/        # Widget definitions (immutable config)\n│       ├── Theming/        # Theme system and built-in themes\n│       └── Input/          # Keyboard input and bindings\n├── samples/                # Example applications\n├── docs/                   # Architecture \u0026 reference documentation\n├── tests/\n│   └── Hex1b.Tests/        # Unit tests\n└── apphost.cs              # Aspire app host for running samples\n```\n\n## 📚 Documentation\n\nFull documentation lives at **[hex1b.dev](https://hex1b.dev)**. Highlights:\n\n- [Input Handling](https://hex1b.dev/guide/input) — focus, routing, declarative\n  bindings, and Vim/Emacs-style remap walkthrough.\n- [Keybinding Portability](https://hex1b.dev/guide/keybinding-portability) —\n  per-terminal interception matrix (Windows Terminal, ConPTY, macOS\n  Terminal.app, iTerm2, Ghostty, kitty, GNOME Terminal, Ptyxis, xterm,\n  tmux, ssh) plus cross-cutting ANSI protocol limits.\n- [Terminal Emulator](https://hex1b.dev/guide/terminal-emulator) — using the\n  embedded terminal widget.\n- [API Reference](https://hex1b.dev/reference/) — generated namespace docs.\n\nIn-repo design / architecture notes (not on the website):\n\n- [`docs/terminal.md`](./docs/terminal.md) — Presentation/workload adapter\n  architecture.\n- [`docs/child-process-arch.md`](./docs/child-process-arch.md) — Child\n  process / PTY architecture.\n- [`docs/muxer-protocol.md`](./docs/muxer-protocol.md) — Muxer wire protocol.\n\nFor the manual portability harness used to generate the per-terminal data,\nsee [`samples/KeyBindingTester`](./samples/KeyBindingTester/README.md).\n\n## 🤝 Contributing\n\nContributions are welcome! Please see [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.\n\nFor AI coding agents, see [AGENTS.md](AGENTS.md) for context and conventions.\n\n## 📄 License\n\nThis project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.\n\n## 🔗 Related Projects\n\n- [Spectre.Console](https://spectreconsole.net/) - Beautiful console output\n- [Terminal.Gui](https://github.com/gui-cs/Terminal.Gui) - Cross-platform terminal UI toolkit\n- [Aspire](https://aspire.dev/) - Cloud-ready stack for .NET\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmitchdenny%2Fhex1b","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmitchdenny%2Fhex1b","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmitchdenny%2Fhex1b/lists"}