TerminalNinja

WPF-inspired TUI for .NET, built native AOT-first.

Build rich terminal interfaces with a familiar dependency property system, XAML markup, data binding, theming, and modern rendering — designed for performance and deployment simplicity.

Why TerminalNinja

Getting Started

Create your first TerminalNinja app in a few minutes.

  1. Create a console app targeting net10.0.
  2. Add a project reference to TerminalNinja.
  3. Define your UI in XAML and load it with TerminalXaml.Load.
using TerminalNinja.App;
using TerminalNinja.Controls;
using TerminalNinja.Xaml;

using var app = new Application(new ApplicationOptions
{
    TargetFps = 60,
    EnableMouseTracking = true,
    EnableTabNavigation = true
});

app.ThemeName = "GruvboxDark";

var window = TerminalXaml.Load<Window>(XamlLayouts.MainLayout, viewModel);
window.Show();
app.Run();
<Window xmlns='http://schemas.terminalninja.dev/xaml'
        Title='My App' Width='80' Height='24'>
  <StackPanel Orientation='Vertical'>
    <TextBlock Text='Welcome to TerminalNinja' />
    <Button Text='Click Me' Command='{Binding ClickCommand}' />
  </StackPanel>
</Window>

WPF Concepts in the Terminal

TerminalNinja keeps WPF mental models so desktop developers can move fast.

Dependency Properties

Control state is DP-backed for metadata, callbacks, styling, and binding support.

XAML-First UI

Describe UI declaratively with the TerminalNinja XML namespace and familiar property syntax.

Binding + DataContext

Use {Binding}, RelativeSource, converters, and MVVM patterns.

Resources + Styles

Share values with StaticResource and apply consistent look with Style/Setter.

Samples

Explore working examples that demonstrate every major feature.

Button

Interactive button with ICommand binding, hover/focus colors, and keyboard support.

View docs →

CheckBox

Toggle control with [x] / [ ] indicator and content label.

View docs →

RadioButton

Mutually exclusive option with (*) / ( ) indicator and GroupName.

View docs →

ComboBox

Dropdown selection control with popup item list.

View docs →

TextBox

Editable text input with caret, selection, and placeholder support.

View docs →

ListBox

Selectable list with keyboard navigation and ObservableCollection binding.

View docs →

ListView

Multi-column data display with headers, grid lines, and row selection.

View docs →

TreeView

Hierarchical data display with expand/collapse navigation.

View docs →

TabControl

Tabbed content switching with header strip and keyboard navigation.

View docs →

ScrollViewer

Scrollable viewport with keyboard and mouse wheel navigation.

View docs →

ProgressBar

Determinate, indeterminate, and styled progress indicators.

View docs →

DataGrid

Read-only multi-column grid with sorting indicators and row selection.

View docs →

ColorPicker

Color selection with palette grid, hex entry, and preview swatch.

View docs →

FilePicker

Modal dialog for browsing and selecting files.

View docs →

FolderPicker

Modal dialog for browsing and selecting a folder.

View docs →

Image

Pixel rendering using half-block characters for 2x vertical resolution.

View docs →

NumberPicker

Numeric input with arrow key increment/decrement and direct digit entry.

View docs →

DatePicker

Date input with field-by-field editing and calendar icon.

View docs →

TimePicker

Time input with hours/minutes/seconds fields and clock icon.

View docs →

DateTimePicker

Combined date and time input with calendar icon.

View docs →

Grid Layout

Rows, columns, star/fixed sizing, and row/column spans.

View docs →

StackPanel Layout

Vertical/horizontal stacking with Auto, Fixed, and Stretch sizing.

View docs →

Data Binding

One-way and two-way binding, value converters, and animated colors.

View docs →

Dialogs

Modal dialogs with OK/Cancel, dimmed background, and async results.

View docs →

Theming

TerminalNinja ships with three built-in themes that apply implicit styles and color resources across all controls. Set the theme on the Application instance:

app.ThemeName = "Dark";      // VS Code-inspired dark
app.ThemeName = "Dracula";   // Dracula color scheme
app.ThemeName = "GruvboxDark"; // Gruvbox dark palette

Themes define 58 color resource keys and implicit styles for all built-in controls. Load custom themes from file or XAML string:

app.LoadThemeFromFile("MyTheme.xaml");
app.LoadThemeFromXaml(customXaml);

Try switching themes in the playground.

XAML Hot Reload

TerminalNinja automatically enables XAML hot reload when a debugger is attached. Edit any .xaml file and save — the UI updates instantly without restarting. ViewModels and application state are preserved.

// Automatic — just run with debugger attached
// Or enable manually:
app.EnableHotReload("path/to/project");

Hot reload works by watching .xaml files with FileSystemWatcher, re-parsing on change via TerminalXaml.LoadFromStream, and swapping the control tree. Source-generated registries (control factories, property accessors) are unaffected — only the view is reloaded. XAML parse errors are caught gracefully, not crashes.