RazorConsole
Build agentic TUI applications with .NET Razor and Spectre.Console
Install / Use
/learn @RazorConsole/RazorConsoleREADME
RazorConsole
Build rich, interactive console applications using familiar Razor syntax and the power of Spectre.Console
</div>🎯 What is RazorConsole?
RazorConsole bridges the gap between modern web UI development and console applications. It lets you create sophisticated terminal interfaces using Razor components, complete with interactive elements, rich styling, and familiar development patterns.
📦 Install
dotnet add package RazorConsole.Core
🚀 Usage
Project Setup
RazorConsole requires the Microsoft.NET.Sdk.Razor SDK to compile Razor components. Update your project file (.csproj) to use the Razor SDK:
<Project Sdk="Microsoft.NET.Sdk.Razor">
<!-- other settings -->
</Project>
Basic Example
Here's a simple counter component to get you started:
Counter.razor
@using Microsoft.AspNetCore.Components
@using Microsoft.AspNetCore.Components.Web
@using RazorConsole.Components
<Columns>
<p>Current count</p>
<Markup Content="@currentCount.ToString()" Foreground="@Spectre.Console.Color.Green" />
</Columns>
<TextButton Content="Click me"
OnClick="IncrementCount"
BackgroundColor="@Spectre.Console.Color.Grey"
FocusedColor="@Spectre.Console.Color.Blue" />
@code {
private int currentCount = 0;
private void IncrementCount()
{
currentCount++;
}
}
Program.cs
using Microsoft.Extensions.Hosting;
using RazorConsole.Core;
IHostBuilder hostBuilder = Host.CreateDefaultBuilder(args)
.UseRazorConsole<Counter>();
IHost host = hostBuilder.Build();
await host.RunAsync();
For more complete sample applications, check out the Examples section below.
✨ Key Features
🧩 Component-Based Architecture
Build your console UI using familiar Razor components with full support for data binding, event handling, and component lifecycle methods.
🎮 Interactive Components
Create engaging user experiences with interactive elements like buttons, text inputs, selectors, and keyboard navigation - all with focus management handled automatically.
🎯 Built-in Component Library
Get started quickly with 25+ pre-built components covering layout, input, display, and navigation needs:
- Layout (8):
Align,Columns,FlexBox,Rows,Grid,Padder,Scrollable,ViewHeightScrollable - Input (3):
TextInput,TextButton,Select - Display (12):
BarChart,BreakdownChart,StepChart,Border,Figlet,Markdown,Markup,ModalWindow,Panel,SpectreCanvas,SyntaxHighlighter,Table - Utilities (2):
Spinner,Newline
For a full list of components and usage details, see the Built-in Components section below.
⚡ Hot Reload Support
Experience rapid development with built-in hot reload support. See your UI changes instantly without restarting your application.
🎪 Interactive Component Gallery
Explore all components hands-on with the included interactive gallery tool. Install globally and run razorconsole-gallery to see live examples of every component in action.
For more details, see the Component Gallery section below.
Built-in components
RazorConsole ships with a catalog of ready-to-use components that wrap Spectre.Console constructs:
Align– position child content horizontally and vertically within a fixed box.BarChart– Renders a horizontal bar chart with optional label, colors and value display.Border– draw Spectre borders with customizable style, color, and padding.BreakdownChart– Renders a colorful breakdown (pie-style) chart showing proportions with optional legend and values.Columns– arrange items side-by-side, optionally stretching to fill the console width.Figlet– render big ASCII art text using FIGlet fonts.FlexBox– lay out child items using a CSS-like flexbox model with configurable direction, justification, alignment, wrapping, and gap.Grid– build multi-row, multi-column layouts with precise cell control.Markup– emit styled text with Spectre markup tags.Markdown- render markdown string.ModalWindow– display modal overlay windows with automatic centering using z-index positioning.Newline– insert intentional spacing between renderables.Padder– add outer padding around child content without altering the child itself.Panel– frame content inside a titled container with border and padding options.Rows– stack child content vertically with optional expansion behavior.Scrollable- enables keyboard-based vertical scrolling through the component's content, including nested components or HTML markup.Select– present a focusable option list with keyboard navigation.SpectreCanvas- draws an array of pixels with different colors.Spinner– show animated progress indicators using Spectre spinner presets.StepChart– Renders a terminal step chart using Unicode box-drawing characters. Perfect for displaying discrete value changes over time or categories.SyntaxHighlighter– colorize code snippets using ColorCode themes.Table– display structured data in formatted tables with headers, borders, and rich cell content.TextButton– display clickable text with focus and pressed-state styling.TextInput– capture user input with optional masking and change handlers.ViewHeightScrollable– scroll any content line-by-line with keyboard navigation and optional embedded scrollbar support forPanel,Border, andTable.
See design-doc/builtin-components.md for the full reference, including parameters and customization tips.
Custom Translators
RazorConsole uses a Virtual DOM (VDOM) translation system to convert Razor components into Spectre.Console renderables. You can extend this system by creating custom translators to support additional Spectre.Console features or build entirely custom components.
Creating a Custom Translator
Implement the IVdomElementTranslator interface to create a custom translator:
using RazorConsole.Core.Rendering.Vdom;
using RazorConsole.Core.Vdom;
using Spectre.Console;
using Spectre.Console.Rendering;
public sealed class OverflowElementTranslator : IVdomElementTranslator
{
// Lower priority values are processed first (1-1000+)
public int Priority => 85;
public bool TryTranslate(VNode node, TranslationContext context, out IRenderable? renderable)
{
renderable = null;
// Check if this is a div with overflow attribute
if (node.Kind != VNodeKind.Element ||
!string.Equals(node.TagName, "div", StringComparison.OrdinalIgnoreCase))
{
return false;
}
if (!node.Attributes.TryGetValue("data-overflow", out var overflowType))
{
return false;
}
// Translate child nodes
if (!VdomSpectreTranslator.TryConvertChildrenToRenderables(
node.Children, context, out var children))
{
return false;
}
var content = VdomSpectreTranslator.ComposeChildContent(children);
// Create renderable with overflow handling
renderable = overflowType?.ToLowerInvariant() switch
{
"ellipsis" => new Padder(content).Overflow(Overflow.Ellipsis),
"crop" => new Padder(content).Overflow(Overflow.Crop),
"fold" => new Padder(content).Overflow(Overflow.Fold),
_ => content
};
return true;
}
}
Registering a Custom Translator
Register your translator in your application's service configuration:
using Microsoft.Extensions.Hosting;
using RazorConsole.Core;
using RazorConsole.Core.Vdom;
IHostBuilder hostBuilder = Host.CreateDefaultBuilder(args)
.UseRazorConsole<MyComponent>(configure: config =>
{
config.ConfigureServices(services =>
{
// Register your custom translator
services.AddVdomTranslator<OverflowElementTranslator>();
});
}
);
IHost host = hostBuilder.Build();
await host.RunAsync();
Using Custom Translators in Components
Once registered, use your custom translator in Raz
