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 MiniTui

The example app, recorded from its own frames. The text is real: pause and select it.

The Widgets demo: a list, a gauge, a sparkline, a canvas and Unicode text

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.

Widgets
The command palette open over the demo menu

Screens 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 components
Split panes with a list, a sortable table and a detail view

Layout

Constraints solved with exact integer arithmetic, so regions never overlap or drop a cell, and split panes you drag with the mouse.

Layout
A table of 500 services loaded from a fake HTTP API

Async 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.

Async data and HTTP
The editor demo with line numbers, a scrollbar and the find bar

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 terminal
var 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.

Testing

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.

The counter app: a box with Count: 3, and the key hints in the status bar

Getting started

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();