AvaloniaTerminal 1.0.0-alpha.13
dotnet add package AvaloniaTerminal --version 1.0.0-alpha.13
NuGet\Install-Package AvaloniaTerminal -Version 1.0.0-alpha.13
<PackageReference Include="AvaloniaTerminal" Version="1.0.0-alpha.13" />
<PackageVersion Include="AvaloniaTerminal" Version="1.0.0-alpha.13" />
<PackageReference Include="AvaloniaTerminal" />
paket add AvaloniaTerminal --version 1.0.0-alpha.13
#r "nuget: AvaloniaTerminal, 1.0.0-alpha.13"
#:package AvaloniaTerminal@1.0.0-alpha.13
#addin nuget:?package=AvaloniaTerminal&version=1.0.0-alpha.13&prerelease
#tool nuget:?package=AvaloniaTerminal&version=1.0.0-alpha.13&prerelease
AvaloniaTerminal
Avalonia terminal control built on top of XTerm.NET.

Features
- Terminal rendering backed by
XTerm.NET - Standalone
Terminalwrapper for direct engine integration - Scrollback with mouse wheel, scrollbar,
PageUp, andPageDown - Caret rendering with theme-aware default styling
- Text selection with drag, double-click word selection, triple-click row selection, and drag auto-scroll
- Bindable selection state via
SelectedTextandHasSelection - Search helpers for finding and navigating matches in the terminal buffer
- Mouse reporting mode support for xterm-compatible terminal apps
- Host-friendly context menu and clipboard hooks
- Configurable right-click behavior via
RightClickAction - Model-driven API for feeding terminal output and sending user input
- Sample desktop app with
Shell,Scroll, andSelectiontabs - Windows sample shell backed by ConPTY, with redirected-shell fallback when ConPTY is unavailable
- Sample shell disables resize reflow to avoid TUI resize corruption in apps such as
mc
Install
dotnet add package AvaloniaTerminal
Basic Usage
Add the control in XAML:
<Window
xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:terminal="using:AvaloniaTerminal">
<terminal:TerminalControl Name="TerminalView" />
</Window>
Create and assign a TerminalControlModel in code-behind or a view model:
using Avalonia.Controls;
namespace MyApp;
public partial class MainWindow : Window
{
private readonly TerminalControlModel _terminal = new();
public MainWindow()
{
InitializeComponent();
TerminalView.Model = _terminal;
}
}
You can also pass AvaloniaTerminal.TerminalOptions when you need non-default terminal behavior:
var model = new TerminalControlModel(new TerminalOptions
{
Cols = 120,
Rows = 30,
ReflowOnResize = false,
});
Feed terminal output:
_terminal.Feed("Hello from AvaloniaTerminal\r\n");
Receive user input:
_terminal.UserInput += bytes =>
{
// Send bytes to a pty, process stdin, socket, ssh session, etc.
};
Common Integration Pattern
The usual flow is:
- Create a
TerminalControlModel - Bind or assign it to
TerminalControl.Model - Forward terminal output into
model.Feed(...) - Forward
model.UserInputto your process or remote shell
Example with a local process or remote session:
var model = new TerminalControlModel();
model.UserInput += bytes =>
{
process.StandardInput.BaseStream.Write(bytes, 0, bytes.Length);
process.StandardInput.BaseStream.Flush();
};
_ = Task.Run(async () =>
{
var buffer = new byte[4096];
while (true)
{
var read = await process.StandardOutput.BaseStream.ReadAsync(buffer);
if (read == 0)
{
break;
}
model.Feed(buffer, read);
}
});
Core APIs
TerminalControlModel:
Feed(string)/Feed(byte[], int)for terminal outputSend(string)/Send(byte[])for programmatic inputScrollLines(int),PageUp(),PageDown(),ScrollToYDisp(int)ScrollToPosition(double),EnsureCaretIsVisible()StartSelection(int, int),StartSelectionFromSoftStart(),SetSoftSelectionStart(int, int)DragExtendSelection(int, int),ShiftExtendSelection(int, int)SelectWordOrExpression(int, int),SelectRow(int),SelectAll(),ClearSelection()Search(string),SelectNextSearchResult(),SelectPreviousSearchResult()SelectedText,HasSelectionTitleScrollOffset,MaxScrollback,ScrollPosition,ScrollThumbsize,CanScrollCaretColumn,CaretRow,IsCaretVisibleIsMouseModeActiveSizeChangedTerminal,SearchServiceOptionAsMetaKey
Terminal:
Feed(string)/Feed(byte[], int)for terminal outputResize(int, int)SwitchToAltBuffer(),SwitchToNormalBuffer()TitleChangedEngine,Buffer,Selection,IsAlternateBufferActiveCols,Rows,Title
TerminalControl:
ModelSelectedText,HasSelectionRightClickActionIsMouseModeActiveFontFamily,FontSize,CaretBrush,SelectionBrushSelectAll()CopySelection()CopySelectionAsync()Paste(string)PasteFromClipboardAsync()Search(string)SelectNextSearchResult()SelectPreviousSearchResult()ContextRequested
TerminalOptions used by TerminalControlModel:
ColsRowsScrollbackConvertEolTabStopWidthTermNameReflowOnResize
Selection And Context Menus
Clients often want to enable a context menu item only when text is selected. TerminalControl exposes that directly:
if (TerminalView.HasSelection)
{
var text = TerminalView.CopySelection();
}
You can also bind against SelectedText and HasSelection from the control or the model, or handle ContextRequested for a custom menu.
Selection behavior:
- drag selects text
- double-click selects a word or expression
- triple-click selects a full row
- dragging above or below the viewport auto-scrolls and keeps extending the selection
Right-click behavior is configurable:
ContextMenu: raiseContextRequestedCopyOrPaste: copy when selection exists, otherwise paste from the clipboardNone: ignore right-click
Example:
<terminal:TerminalControl RightClickAction="CopyOrPaste" />
Programmatic clipboard helpers:
await TerminalView.CopySelectionAsync();
await TerminalView.PasteFromClipboardAsync();
ContextRequested carries:
- pointer position relative to the control
- current
SelectedText - current
HasSelection
Search
Search is buffer-based
var count = TerminalView.Search("error");
if (count > 0)
{
TerminalView.SelectNextSearchResult();
}
Useful model properties:
SearchResultCountCurrentSearchResultIndexLastSearchText
Mouse Reporting
When the terminal application enables mouse reporting, TerminalControl forwards pointer press, release, and motion events to XTerm.NET instead of using them for text selection. This allows interactive terminal applications to receive mouse input.
This is controlled by the terminal app, not by the Avalonia host. If an app does not switch the terminal into xterm mouse mode, the control will keep using the pointer for normal text selection.
Styling
The library defines its default terminal styling in:
The desktop sample includes those resources automatically. If you host the control yourself, include the style resource in your application:
<Application.Styles>
<StyleInclude Source="avares://AvaloniaTerminal/Styles/Colors.axaml" />
</Application.Styles>
Colors.axaml provides:
- the default
TerminalControlfont settings - the exported 256-color terminal palette as
AvaloniaTerminalColor0throughAvaloniaTerminalColor255 - resource keys that the control reads for optional caret and selection overrides
Available resource keys:
AvaloniaTerminalFontFamilyAvaloniaTerminalFontSizeAvaloniaTerminalCaretBrushAvaloniaTerminalSelectionBrushAvaloniaTerminalColor0...AvaloniaTerminalColor255
You can override those resources at the application level to align the terminal with your app theme:
<Application.Resources>
<x:String x:Key="AvaloniaTerminalFontFamily">Fira Code</x:String>
<x:Double x:Key="AvaloniaTerminalFontSize">14</x:Double>
<SolidColorBrush x:Key="AvaloniaTerminalCaretBrush" Color="#FFB000" />
<SolidColorBrush x:Key="AvaloniaTerminalSelectionBrush" Color="#4060A0FF" />
<SolidColorBrush x:Key="AvaloniaTerminalColor0" Color="#111111" />
<SolidColorBrush x:Key="AvaloniaTerminalColor15" Color="#F5F5F5" />
</Application.Resources>
TerminalControl also exposes direct styling hooks when you want to customize a single instance:
FontFamilyFontSizeCaretBrushSelectionBrush
Example:
<terminal:TerminalControl
FontFamily="JetBrains Mono"
FontSize="13"
CaretBrush="Orange"
SelectionBrush="#4060A0FF" />
Notes:
- font defaults come from
Colors.axamland can be overridden by application resources - caret and selection use the control properties first, then the corresponding application resources, then the built-in fallback behavior
- ANSI foreground/background rendering uses the exported
AvaloniaTerminalColor*resource keys, so hosts can replace the palette without changing library code
Samples
The repo includes a shared samples project and a desktop sample host.
Current sample tabs:
Shell: starts a platform-appropriate shell- Windows: prefers ConPTY-backed
pwsh.exe, with redirected fallback - macOS/Linux: uses the existing redirected-shell sample backend
- uses
RightClickAction="CopyOrPaste" - constructs the model with
ReflowOnResize = falseto keep full-screen TUIs stable during window resize
- Windows: prefers ConPTY-backed
Scroll: preloaded scrollback sampleSelection: demonstrates selection and bindable selected text
Desktop sample host:
Shared sample controls:
src/AvaloniaTerminal.Samples/ShellControl.axamlsrc/AvaloniaTerminal.Samples/ScrollSampleControl.axamlsrc/AvaloniaTerminal.Samples/SelectionControl.axaml
Running The Sample App
dotnet run --project src/AvaloniaTerminal.Desktop
Sample shell notes
- On Windows, the sample uses ConPTY when available.
- Full-screen TUIs such as
mcrender correctly with the current ambiguous-width fix and with resize reflow disabled in the sample shell. - Mouse interaction in TUIs still depends on the application enabling xterm mouse reporting. Remote Linux apps often do this; some local Windows console apps may not.
Testing
The repo has headless tests covering terminal behavior without needing a visible desktop session.
dotnet test --project tests/AvaloniaTerminal.Tests/AvaloniaTerminal.Tests.csproj -f net10.0
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 is compatible. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories (1)
Showing the top 1 popular GitHub repositories that depend on AvaloniaTerminal:
| Repository | Stars |
|---|---|
|
IvanJosipovic/KubeUI
Kubernetes User Interface
|
| Version | Downloads | Last Updated |
|---|---|---|
| 1.0.0-alpha.13 | 767 | 4/4/2026 |
| 1.0.0-alpha.12 | 64 | 3/30/2026 |
| 1.0.0-alpha.11 | 661 | 3/27/2026 |
| 1.0.0-alpha.10 | 60 | 3/26/2026 |
| 1.0.0-alpha.9 | 45 | 3/26/2026 |
| 1.0.0-alpha.8 | 105 | 3/22/2026 |
| 1.0.0-alpha.7 | 4,385 | 11/1/2025 |
| 1.0.0-alpha.6 | 107 | 10/31/2025 |
| 1.0.0-alpha.5 | 100 | 10/31/2025 |
| 1.0.0-alpha.4 | 182 | 10/31/2025 |
| 1.0.0-alpha.3 | 8,638 | 1/28/2025 |
| 1.0.0-alpha.2 | 144 | 1/24/2025 |
| 1.0.0-alpha.1 | 134 | 1/24/2025 |