Spectre.Console.Rx 1.1.8

dotnet add package Spectre.Console.Rx --version 1.1.8
                    
NuGet\Install-Package Spectre.Console.Rx -Version 1.1.8
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Spectre.Console.Rx" Version="1.1.8" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Spectre.Console.Rx" Version="1.1.8" />
                    
Directory.Packages.props
<PackageReference Include="Spectre.Console.Rx" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Spectre.Console.Rx --version 1.1.8
                    
#r "nuget: Spectre.Console.Rx, 1.1.8"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Spectre.Console.Rx@1.1.8
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Spectre.Console.Rx&version=1.1.8
                    
Install as a Cake Addin
#tool nuget:?package=Spectre.Console.Rx&version=1.1.8
                    
Install as a Cake Tool

Alt

Spectre.Console.Rx

Reactive extensions for Spectre.Console. Compose terminal animations with Rx and keep all UI mutations on a single, deterministic scheduler.

  • Reactive wrappers for Spectre.Console Status, Progress, and Live
  • Single-threaded UI scheduler to keep the console thread-safe
  • Fluent, chainable context APIs
  • Works on .NET Standard 2.0, .NET 8, and .NET 9

Visit https://spectreconsole.net for Spectre.Console docs and https://github.com/spectreconsole/spectre.console for the original source.

Packages

  • Spectre.Console.Rx
  • Spectre.Console.Rx.Json (optional JSON helpers)

Install:

# Core
dotnet add package Spectre.Console.Rx

# Optional JSON helpers
dotnet add package Spectre.Console.Rx.Json

Target frameworks

  • .NET Standard 2.0
  • .NET 8
  • .NET 9

Core concept

The console is not thread-safe. Spectre.Console.Rx enforces a single UI thread via AnsiConsoleRx.Scheduler so all reactive pipelines render on the same thread. Drive animations by pushing work to that scheduler and mark contexts finished when done.

Key points:

  • Always switch to the UI scheduler: .ObserveOn(AnsiConsoleRx.Scheduler)
  • Only one console context (Status/Progress/Live) should run at a time
  • Call IsFinished() on the context to end rendering/animation loops

Quick start

Status

using System.Reactive.Linq;
using Spectre.Console.Rx;

AnsiConsoleRx
    .Status("[yellow]Initializing[/]", s => s.AutoRefresh(true))
    .ObserveOn(AnsiConsoleRx.Scheduler)
    .Subscribe(ctx => ctx.Schedule(async scheduler =>
    {
        await scheduler.Sleep(TimeSpan.FromMilliseconds(800));
        ctx.Status("[blue]Warming up[/]");
        ctx.Spinner(Spinner.Known.Dots);

        await scheduler.Sleep(TimeSpan.FromMilliseconds(800));
        ctx.Status("[green]Ready[/]");

        ctx.IsFinished();
    }));

Live (animate a renderable)

using System.Reactive.Linq;
using Spectre.Console.Rx;

var table = new Table().AddColumn("Col").AddRow("Row 1");

AnsiConsoleRx
    .Live(table, ld => ld.AutoClear(false))
    .ObserveOn(AnsiConsoleRx.Scheduler)
    .Subscribe(ctx =>
    {
        // Chain updates in-place (blocking) for simple demos
        ctx
            .Update(250, () => table.AddRow("Row 2"))
            .Update(250, () => table.AddRow("Row 3"))
            .Update(250, () => table.AddRow("Done"));

        ctx.IsFinished();
    });

Progress

using System.Reactive.Linq;
using Spectre.Console.Rx;

AnsiConsoleRx
    .Progress(p => p.AutoClear(false)
        .Columns(new ProgressColumn[]
        {
            new TaskDescriptionColumn(),
            new ProgressBarColumn(),
            new PercentageColumn(),
            new RemainingTimeColumn(),
            new SpinnerColumn(),
        }))
    .ObserveOn(AnsiConsoleRx.Scheduler)
    .Subscribe(async ctx =>
    {
        var t1 = ctx.AddTask("Downloading").IsIndeterminate(false);
        var t2 = ctx.AddTask("Processing");

        await ctx.Schedule(TimeSpan.FromMilliseconds(100), () =>
        {
            t1.Increment(2);
            if (t1.Value >= 100) t2.Increment(4);
        });

        // Progress completes automatically when all started tasks are finished
    });

Threading model and scheduling

  • AnsiConsoleRx.Scheduler is a single-threaded scheduler. It hosts a SynchronizationContext and processes posted work sequentially.
  • Use .ObserveOn(AnsiConsoleRx.Scheduler) in your observable pipelines before mutating UI.
  • Use context scheduling helpers to perform timed loops without blocking your app thread.

Context scheduling helpers

All helpers run on the Spectre scheduler and update the UI safely.

  • Task Schedule(this IContext context, TimeSpan delay, Func<bool> isComplete, Action action)

    • Executes action repeatedly every delay until isComplete() returns true. Calls context.Refresh() after each iteration.
  • Task Schedule(this IContext context, Action<SpectreConsoleScheduler> action)

    • Executes an action on the scheduler. Useful to sequence async sleeps and UI updates.
  • Task<T> Schedule<T>(this IContext context, Func<SpectreConsoleScheduler, Task<T>> action)

    • Executes an async function on the scheduler and returns its result.
  • Task Schedule(this IContext context, TimeSpan delay, Action action) (ProgressContext only)

    • Repeats action every delay until all started progress tasks report finished.

The SpectreConsoleScheduler provides Sleep(TimeSpan) for non-blocking waits and follows IScheduler from Rx.

API reference (most used)

AnsiConsoleRx

  • ISpectreConsoleScheduler Scheduler � the UI scheduler instance
  • IObservable<StatusContext> Status(string status, Func<Status, Status>? configure = null)
  • IObservable<ProgressContext> Progress(Func<Progress, Progress>? configure = null)
  • IObservable<LiveDisplayContext> Live(IRenderable renderable, Func<LiveDisplay, LiveDisplay>? configure = null)
  • IObservable<(ProgressContext context, ProgressTask[] tasks)> AddTasks(this IObservable<ProgressContext>, Func<ProgressContext, ProgressTask[]> factory)
  • LiveDisplayContext Update(this LiveDisplayContext ctx, int delayMs, Action action) � simple chained updates (demo-friendly)
  • void IsFinished(this LiveDisplayContext ctx) / void IsFinished(this StatusContext ctx) � signal completion

StatusContext

  • Properties: string Status, Spinner Spinner, Style? SpinnerStyle, bool IsFinished
  • Methods: void Refresh()
  • Extensions: Status(string), Spinner(Spinner), SpinnerStyle(Style?), IsFinished()

ProgressContext

  • Properties: bool IsFinished
  • Methods: ProgressTask AddTask(...), void Refresh(), Task Schedule(TimeSpan delay, Action action)

LiveDisplayContext

  • Properties: bool IsFinished
  • Methods: void UpdateTarget(IRenderable? target), void Refresh()
  • Extensions: Update(int delayMs, Action), IsFinished()

JSON helpers (optional)

Spectre.Console.Rx.Json adds helpers to pretty print JSON with Spectre.Console widgets.

using Spectre.Console.Rx.Json;

var panel = new Panel(new JsonText(jsonString))
    .Header("Data")
    .SquareBorder()
    .BorderColor(Color.LightSkyBlue1);

AnsiConsole.Write(panel);

Best practices

  • Only one Status/Progress/Live should be active at a time (the console is single-threaded)
  • Always .ObserveOn(AnsiConsoleRx.Scheduler) before mutating UI
  • End animations with IsFinished() so observables complete
  • Prefer scheduler Sleep over Thread.Sleep to keep the pump responsive
  • Keep heavy work off the UI scheduler; compute elsewhere, then push results to UI via ObserveOn

Troubleshooting

  • Nothing renders / pipeline hangs
    • Ensure .ObserveOn(AnsiConsoleRx.Scheduler) is applied before Subscribe that updates UI
    • Make sure you call IsFinished() on the context when done
  • Flicker or interleaved output
    • Avoid running multiple contexts concurrently; sequence them
  • Exceptions swallowed
    • Wrap your subscription in Subscribe(onNext, onError, onCompleted) and log onError

Examples

See example projects under src:

  • LiveExample, LiveTableExample
  • StatusExample
  • ProgressExample
  • CombinedExample

License

MIT License. See the LICENSE file for details.

Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  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. 
.NET Core netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 was computed. 
.NET Framework net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (2)

Showing the top 2 NuGet packages that depend on Spectre.Console.Rx:

Package Downloads
Spectre.Console.Rx.Json

A library that extends Spectre.Console with JSON superpowers.

Spectre.Console.Rx.Testing

Contains testing utilities for Spectre.Console.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.1.8 319 9/19/2025
1.0.82 383 3/19/2024
1.0.32 387 12/20/2023
1.0.30 178 12/20/2023
1.0.29 227 12/19/2023
1.0.27 240 11/30/2023
1.0.25 234 11/17/2023
1.0.23 203 11/5/2023
1.0.22 181 11/5/2023
1.0.20 227 10/20/2023
1.0.17 228 9/18/2023
1.0.13 213 9/11/2023
1.0.11 263 8/31/2023
1.0.10 226 8/29/2023
1.0.6 235 8/27/2023
1.0.5 253 8/26/2023

Compatability with Net 8 / 9 / 10 and netstandard2.0