Skip to content

Customization & Output

Repl’s output pipeline is fully composable. The same command graph produces plain text for a CI log, syntax-highlighted JSON for a terminal, and Spectre.Console tables for a rich interactive session — all without touching handler code.

Every command supports output format flags out of the box:

FlagFormat
(none)human — plain text / table
--output:format=json (or --json)JSON
--output:format=xmlXML
--output:format=yamlYAML
--output:format=markdownMarkdown table
--output:format=spectreSpectre.Console rendering
  1. --output:format flag on the command line
  2. ReplOptions.Output.DefaultFormat (configured at startup)
  3. human (built-in default)
app.Options(o =>
{
o.Output.DefaultFormat = "json"; // all commands default to JSON
});

Repl detects the terminal’s color capability at startup and chooses rendering accordingly.

Repl detects the terminal’s color capability at startup and chooses rendering accordingly. Detected capability tiers (informational):

Detected tierRendering
No ANSIPlain text, no escape sequences
Basic16 ANSI colors
Extended256 colors
TrueColor24-bit color

Detection chain (first match wins):

  1. NO_COLOR env var → disable ANSI
  2. CLICOLOR_FORCE env var → force ANSI
  3. TERM / COLORTERM heuristics
  4. Platform-specific checks (Windows Console, VS Code terminal, etc.)
  5. Redirection check (piped stdout → no ANSI)

Override programmatically using AnsiMode:

app.Options(o =>
{
o.Output.AnsiMode = AnsiMode.Always; // force ANSI on regardless of detection
// or: Auto (default — let detection decide), Never (force off)
});

In interactive mode with ANSI support, --json output is automatically syntax-highlighted (keys in one color, strings in another, numbers in a third). No configuration required.


Repl uses the terminal width for table column sizing, word wrap, and layout decisions.

Resolution order:

  1. OutputOptions.PreferredWidth (explicit override)
  2. COLUMNS environment variable
  3. Detected console window width
  4. Telnet NAWS / DTTERM resize for hosted sessions
  5. OutputOptions.FallbackWidth (default: 120)
app.Configure<OutputOptions>(o =>
{
o.PreferredWidth = 160;
o.FallbackWidth = 80;
});

Register a transformer for a new format name:

app.Options(o =>
{
o.Output.AddTransformer("csv", new CsvOutputTransformer());
o.Output.AddAlias("spreadsheet", "csv"); // both --output:format=csv and --output:format=spreadsheet work
});

IOutputTransformer receives the handler’s return value and returns a formatted string:

public class CsvOutputTransformer : IOutputTransformer
{
public string Name => "csv";
public ValueTask<string> TransformAsync(object? value, CancellationToken ct)
{
var csv = value is IEnumerable<object> rows ? ToCsv(rows) : value?.ToString() ?? "";
return ValueTask.FromResult(csv);
}
}

The startup banner (shown in interactive mode) can be suppressed:

Terminal window
myapp --no-logo

Or globally:

app.Options(o =>
{
o.Output.BannerEnabled = false;
// or: o.Output.BannerFormats = ["human"] — show only in human format (default)
});

Add Repl.Spectre and register:

app.UseSpectreConsole(); // enables rich prompts and renderables in one call

Return any IRenderable from a handler — Spectre renders it automatically:

app.Map("contacts table", (IContactStore store) =>
{
var table = new Table()
.BorderStyle(Style.Parse("grey"))
.AddColumn("[bold]Id[/]")
.AddColumn("[bold]Name[/]")
.AddColumn("[bold]Email[/]");
foreach (var c in store.All())
table.AddRow(c.Id.ToString(), c.Name, c.Email);
return table;
});

Use Spectre.Console’s full Markup and Style API anywhere an IRenderable is expected:

return new Markup("[green bold]Success![/] Contact added.");
return new Panel(new Markup(content))
.BorderStyle(Style.Parse("blue"))
.Header("[bold]Summary[/]");
TypeDescription
TableGrid with borders, alignment, and markup
PanelBox with optional header and border
TreeHierarchical tree view
BarChartHorizontal bar chart
BreakdownChartProportion chart
CalendarMonthly calendar with highlighted dates
JsonTextSyntax-highlighted JSON
FigletTextLarge ASCII art text
TextPathBreadcrumb path rendering
MarkupInline styled text
Grid / ColumnsFree-form layout
RuleHorizontal divider
Progress / StatusLive progress widgets

Spectre.Console detects terminal capabilities automatically. On terminals without ANSI support, all output degrades gracefully to plain text — no code changes needed.


Help can also be rendered in structured formats:

Terminal window
myapp contacts --help # human-readable
myapp contacts --help --json # machine-readable JSON

The JSON format returns a structured ReplDocumentationModel — useful for tooling, documentation generators, and agents.


Repl.Spectre registers Spectre’s IAnsiConsole in DI, bound to the current session’s output stream. Inject it directly when you need full Spectre control:

app.Map("demo", (IAnsiConsole console) =>
{
console.Write(new FigletText("Repl").Color(Color.Blue));
console.MarkupLine("[bold green]Ready.[/]");
});

This is session-safe in hosted mode — each session gets its own IAnsiConsole bound to its output stream.