MiniTui
Terminal UIs for .NET: immediate mode, fast, and dependency-free.
Describe the screen every frame, and MiniTui draws only what changed. Widgets, layout, screens and focus, the mouse and the clipboard, themes, and a test harness, on Windows, Linux and macOS.
dotnet add package MiniTuiThe example app, recorded from its own frames. The text is real: pause and select it.
Widgets
Lists, tables, trees, tabs, text fields and editors, gauges, sparklines, line and bar charts, and a braille canvas. Each is a builder that draws into a buffer.
WidgetsScreens and focus
Grow from one render callback to a stack of screens built from components, with focus scopes, dialogs, menus, a command palette and scoped key bindings.
Screens and componentsLayout
Constraints solved with exact integer arithmetic, so regions never overlap or drop a cell, and split panes you drag with the mouse.
LayoutAsync without blocking
HTTP calls and slow work run off the UI thread, and their results come back on it. Loadable<T>
shows loading, errors and retries.
The terminal, done right
Raw input with the kitty keyboard protocol, bracketed paste, mouse and hover, OSC 52 clipboard, light and dark detection, and a terminal that's restored on exit, crashes and Ctrl+Z.
The terminalvar h = new ComponentHarness(new Counter());
h.Press("k k k");
Assert.Contains("Count: 3", h.Lines[2]);
Testable
ComponentHarness runs a screen without a terminal: press keys, click, and assert on the cells it
drew.
A whole app in a screenful
A render callback and a key map. The status bar shows the key hints, q quits, and the terminal
is restored however the app ends.
using MiniTui;
var count = 0;
var app = App.Create();
var keys = new KeyMap()
.Add("k,up", "+1", () => count++)
.Add("j,down", "-1", () => count--)
.Add("q", "Quit", app.Quit);
app.OnKey(keys.Handle)
.Render((buf, screen) =>
{
var inner = Widget.Block().Title(" Counter ").Draw(buf, new Rect(2, 1, 30, 5));
buf.SetString(inner.X + 1, inner.Y + 1, $"Count: {count}", Style.Default.Bold());
Widget.StatusBar().Left(keys.Hints(screen.Width)).Draw(buf, screen);
})
.Run();