Retro.Crt
0.2.1
See the version list below for details.
dotnet add package Retro.Crt --version 0.2.1
NuGet\Install-Package Retro.Crt -Version 0.2.1
<PackageReference Include="Retro.Crt" Version="0.2.1" />
<PackageVersion Include="Retro.Crt" Version="0.2.1" />
<PackageReference Include="Retro.Crt" />
paket add Retro.Crt --version 0.2.1
#r "nuget: Retro.Crt, 0.2.1"
#:package Retro.Crt@0.2.1
#addin nuget:?package=Retro.Crt&version=0.2.1
#tool nuget:?package=Retro.Crt&version=0.2.1
Retro.Crt
A Pascal CRT-Unit-style console library for modern .NET. Tiny, dependency-
free, trim- and AOT-clean. ANSI styling, classic TextColor / GotoXY /
ClrScr verbs, truecolor with graceful 16-color and NO_COLOR fallback,
plus a small set of Pascal-flavoured output building blocks: framed
banners, in-place progress bars, semantic logging, and a typewriter that
fades characters in.
using Retro.Crt;
Crt.TextColor(Color.LightCyan);
Crt.WriteLine("system online.");
using (Crt.WithStyle(Color.Yellow, bold: true))
Crt.WriteLine("> ready.");
Install
dotnet add package Retro.Crt
API reference: https://chloe-dream.github.io/retro-crt
Targets net10.0. No third-party dependencies.
Why
Spectre.Console is great, but it does not trim or AOT cleanly, and a launcher that ships as a 12 MB single binary cannot afford the runtime weight. Retro.Crt is the small, opinionated alternative for tools that want curated colored output, a banner, a progress bar, and nothing else.
Comparison
| Retro.Crt | Spectre.Console | Pastel | Crayon | |
|---|---|---|---|---|
| Trim / AOT clean | ✅ | ❌ | ✅ | ✅ |
| Runtime dependencies | 0 | many | 0 | 0 |
| Truecolor | ✅ | ✅ | ✅ | ❌ |
| Pascal-flavoured verbs | ✅ | ❌ | ❌ | ❌ |
| Framed banner | ✅ | ✅ | ❌ | ❌ |
| Progress bar | ✅ (single) | ✅ (multi/live) | ❌ | ❌ |
| Tables / trees / forms | ❌ | ✅ | ❌ | ❌ |
| Live regions / layout | ❌ | ✅ | ❌ | ❌ |
| Markup language | ❌ | ✅ | ❌ | ❌ |
| Built-in logger | ✅ (tiny) | ❌ | ❌ | ❌ |
If you need tables, trees, forms, layouts, or a markup language — use Spectre.Console. If you need a 12 MB AOT launcher with a charming splash screen, four log levels, and a single progress bar — this library.
How to use
Colors and styling
The 16 classic DOS palette names (LightCyan, Brown, …) map onto the
user's terminal theme via SGR codes — so themed terminals (Solarized,
Dracula, …) keep their identity. Use Color.Rgb(r, g, b) for truecolor.
Crt.TextColor(Color.LightGreen);
Crt.Write("ok");
Crt.ResetColor();
using (Crt.WithStyle(fg: Color.Rgb(255, 140, 0), bold: true))
Crt.WriteLine("warning, in orange");
Crt.ColorEnabled reflects whether escapes will actually reach the
terminal (false when output is redirected, NO_COLOR is set, or VT
enablement failed on Windows). FORCE_COLOR=1 overrides redirection
detection.
Color.TryParse, Color.TryFromHex, and Color.TryFromName accept
hex strings (#RRGGBB, #RGB, with or without the leading hash) and
the canonical DOS palette names (LightCyan, Brown, …, case
insensitive). Useful for reading colors from config files.
if (Color.TryParse(userInput, out var c))
Crt.TextColor(c);
Diagnostics
var report = Diagnostics.Capture();
Console.WriteLine(report);
// ansi=on unicode=on redirected=no TERM=xterm-256color
// enc=utf-8(65001) os=linux
Use this in a startup hook when a user reports "I don't see colors" — the
one-line summary usually contains the answer (NO_COLOR=set,
redirected=stdout, enc=us-ascii, …).
Pascal CRT verbs
Crt.ClrScr();
Crt.GotoXY(10, 5); // 1-based, like the original CRT unit
Crt.Write("hi");
Crt.ClrEol();
Banner
Banner.Box("Retro.Crt 0.2", fg: Color.LightCyan);
Banner.Box(
["Retro.Crt 0.2", "Banner / Bar / Log / Typewriter"],
fg: Color.LightCyan);
Banner.Gradient(
asciiArtLines,
from: Color.Rgb(80, 220, 255),
to: Color.Rgb(255, 120, 175));
Box uses unicode box-drawing glyphs when the terminal can render them,
and falls back to +--+ on legacy ASCII code pages. Gradient
interpolates per line; both endpoints must be truecolor or it falls back
to from.
ProgressBar
using var bar = ProgressBar.Start(
total: 4_500_000,
width: 30,
label: " download",
color: Color.LightCyan);
for (var i = 0; i <= 100; i++)
{
bar.Set(i * 45_000);
Thread.Sleep(40);
}
The bar redraws in place on every Set / Tick, hides the terminal
cursor for its lifetime, and prints a single final frame on Dispose.
When ANSI is unavailable (output redirected, NO_COLOR, dumb terminal)
intermediate updates are suppressed and only the final frame is written —
so log files do not end up with sixty progress lines in a row.
Log
Log.Debug("loading config from /etc/retro");
Log.Info("system online");
Log.Success("checksum verified");
Log.Warn("disk usage at 84%");
Log.Error("failed to bind port 8080");
Format: HH:MM:SS LEVEL message with a fixed five-char level tag so
columns line up. Warn and Error go to stderr; everything else to
stdout.
Typewriter
Reveals text one character at a time. Optional fake cursor between characters and optional alpha fade-in (the final glyph appears in its target color but ramps from dim to full brightness). The terminal's native cursor is hidden for the whole reveal.
Typewriter.TypeLine(
"system online.",
msPerChar: 25,
fg: Color.LightCyan);
Typewriter.TypeLine(
"with a fake cursor...",
msPerChar: 30,
fg: Color.LightGreen,
cursor: TypewriterCursor.Block);
Typewriter.TypeLine(
"alpha fade-in (truecolor)...",
msPerChar: 50,
fg: Color.Rgb(255, 120, 200),
fade: TypewriterFade.Alpha);
Typewriter.TypeLine(
"gradient + cursor + alpha fade",
msPerChar: 40,
cursor: TypewriterCursor.Block,
fade: TypewriterFade.Alpha,
gradient: (Color.Rgb(80, 220, 255), Color.Rgb(255, 120, 175)));
Alpha fade requires truecolor — on Standard16 it silently degrades to
no fade (Standard16 has no brightness scaling). When ANSI is off both
cursor and fade are skipped and the string is dumped at full speed —
still typed, but without animation residue in logs.
The cursor and fade animations assume one terminal cell per char, so
emoji (surrogate pairs), combining marks, and wide CJK glyphs aren't
correctly tracked. Stick to BMP single-cell characters when animating.
TypeAsync / TypeLineAsync are the awaitable variants — same shape,
plus a CancellationToken. Cancellation aborts the reveal mid-string;
the finally block still erases the trailing cursor, restores color,
and re-shows the terminal cursor before the
OperationCanceledException propagates.
using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(2));
try
{
await Typewriter.TypeLineAsync(
"running...", msPerChar: 40, fg: Color.LightCyan,
cancellationToken: cts.Token);
}
catch (OperationCanceledException) { /* terminal is in a clean state */ }
Building from source
git clone https://github.com/chloe-dream/retro-crt
cd retro-crt
dotnet build
dotnet test
dotnet run --project samples/Retro.Crt.Demo
NuGet package
The library project is already packable. Build a .nupkg locally with:
dotnet pack src/Retro.Crt/Retro.Crt.csproj -c Release
Output lands in src/Retro.Crt/bin/Release/Retro.Crt.<version>.nupkg
(plus a .snupkg symbol package — IncludeSymbols is on).
To publish to nuget.org, set up an API key and:
dotnet nuget push src/Retro.Crt/bin/Release/Retro.Crt.0.2.0.nupkg \
--api-key $NUGET_API_KEY \
--source https://api.nuget.org/v3/index.json
The package is not published yet — version 0.2.0 is the first one worth shipping (Stage 1 was barely a library).
Roadmap
See ROADMAP.md. Stage 3 sketches a cell-grid screen buffer with diff renderer for Turbo-Vision-style shadows, save/restore-rect, and flicker-free repaint.
Status
Pre-1.0. Public API may move between minor versions until 1.0.
License
MIT
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | 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. |
-
net10.0
- No dependencies.
NuGet packages (1)
Showing the top 1 NuGet packages that depend on Retro.Crt:
| Package | Downloads |
|---|---|
|
Retro.Crt.Tui
Text User Interface widgets on top of Retro.Crt's cell-buffer / diff-renderer core. Layout, focus, mouse + keyboard, scrollable log viewer, dialogs — DOS-style UI in a modern terminal. Tiny, dependency-free, trim- and AOT-clean. |
GitHub repositories
This package is not used by any popular GitHub repositories.