Skip to content

Getting Started ​

RoyalTerminal is a modular terminal stack, not a single UI control package. The smallest successful setup depends on whether you want:

  • a managed Avalonia terminal with no native VT dependency
  • an Avalonia terminal that can use the official Ghostty VT engine
  • lower-level transport, rendering, or profile infrastructure without the demo app

Choose the package set ​

ScenarioRequired packages
Avalonia terminal with managed VT fallbackRoyalApps.RoyalTerminal.Avalonia
Avalonia terminal with native Ghostty VT availableRoyalApps.RoyalTerminal.Avalonia, RoyalApps.RoyalTerminal.Terminal.Vt.Ghostty; restore or publish with your target RID so NuGet selects the matching native asset package
Avalonia settings surfaceadd RoyalApps.RoyalTerminal.Avalonia.Settings
SSH agent auth for the SSH.NET transportadd RoyalApps.RoyalTerminal.Terminal.Transport.Ssh.SshNet.Agent

Native asset packages selected by runtime.json:

  • macOS: RoyalApps.RoyalTerminal.GhosttySharp.Native.OSX
  • Windows: RoyalApps.RoyalTerminal.GhosttySharp.Native.Win64
  • Linux: RoyalApps.RoyalTerminal.GhosttySharp.Native.Linux64

Install the packages ​

Managed-only Avalonia setup:

bash
dotnet add package RoyalApps.RoyalTerminal.Avalonia

Avalonia plus native Ghostty VT:

bash
dotnet add package RoyalApps.RoyalTerminal.Avalonia
dotnet add package RoyalApps.RoyalTerminal.Terminal.Vt.Ghostty
dotnet publish -r osx-arm64

Replace osx-arm64 with the RID you publish or restore for, such as win-x64, win-arm64, linux-x64, linux-arm64, or osx-x64. Direct native package references are only needed when you intentionally want to force a specific native asset package.

Add a TerminalControl ​

In XAML, host TerminalControl like any other Avalonia control:

xml
<Window
    xmlns="https://github.com/avaloniaui"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:rt="clr-namespace:RoyalTerminal.Avalonia.Controls;assembly=RoyalTerminal.Avalonia">
  <rt:TerminalControl
      x:Name="Terminal"
      Columns="120"
      Rows="36"
      ScrollbackLimit="10000"
      TerminalFontSize="14" />
</Window>

Start a local PTY session ​

StartSessionAsync(...) is the preferred entry point. It routes through the transport abstraction and keeps the control aligned with the shared session-service pipeline.

csharp
using RoyalTerminal.Avalonia.Controls;
using RoyalTerminal.Terminal;

public static async Task StartAsync(TerminalControl terminal)
{
    TerminalSessionDimensions dimensions = new(
        Columns: 120,
        Rows: 36,
        WidthPixels: 1200,
        HeightPixels: 800);

    PtyTransportOptions options = new(
        Command: null,
        WorkingDirectory: Environment.GetFolderPath(Environment.SpecialFolder.UserProfile),
        Environment: null,
        Dimensions: dimensions);

    await terminal.StartSessionAsync(options);
}

StartPty(...) still exists for compatibility, but new integrations should prefer StartSessionAsync(...) or the typed helpers such as StartSshAsync(...).

Start an SSH session ​

The SSH transport uses the same session pipeline and option model:

csharp
using RoyalTerminal.Avalonia.Controls;
using RoyalTerminal.Terminal;

TerminalControl terminal = new();

SshTransportOptions options = new(
    Endpoint: new SshEndpointOptions("example.com", 22, "alice"),
    RequestPty: true,
    TerminalType: "xterm-256color",
    InitialCommand: null,
    Authentication: new SshAuthenticationOptions(
        UsePassword: true,
        PasswordSecretId: "demo-password",
        PrivateKeySecretIds: Array.Empty<string>(),
        UseAgent: false),
    Dimensions: new TerminalSessionDimensions(120, 40, 1200, 800))
{
    ExpectedHostKeyFingerprintSha256 = "SHA256:BASE64_FINGERPRINT",
};

await terminal.StartSshAsync(options);

If ExpectedHostKeyFingerprintSha256 is not set, the default trust path falls back to KnownHostsSshHostKeyValidator and OpenSSH known_hosts.

Enable native VT explicitly ​

If you want strict native-VT behavior instead of automatic fallback, set VtProcessorPreference to Native and add the Ghostty VT provider package plus native runtime assets:

csharp
using RoyalTerminal.Avalonia.Controls;
using RoyalTerminal.Avalonia.Services;
using RoyalTerminal.Terminal;
using RoyalTerminal.Terminal.Services;

TerminalControl terminal = new(
    new TerminalSessionService(),
    new DefaultTerminalInputAdapter(),
    new DefaultTerminalSelectionService(),
    new DefaultTerminalScrollService(),
    new DefaultVtProcessorFactory([new GhosttyVtProcessorProvider()]),
    new DefaultPtyFactory())
{
    VtProcessorPreference = VtProcessorPreference.Native,
};

Use Auto when you want the native processor when available and the managed processor otherwise.

Where to go next ​

MIT Licensed