![]() |
VOOZH | about |
dotnet add package Reactive.Wasm --version 3.0.1
NuGet\Install-Package Reactive.Wasm -Version 3.0.1
<PackageReference Include="Reactive.Wasm" Version="3.0.1" />
<PackageVersion Include="Reactive.Wasm" Version="3.0.1" />Directory.Packages.props
<PackageReference Include="Reactive.Wasm" />Project file
paket add Reactive.Wasm --version 3.0.1
#r "nuget: Reactive.Wasm, 3.0.1"
#:package Reactive.Wasm@3.0.1
#addin nuget:?package=Reactive.Wasm&version=3.0.1Install as a Cake Addin
#tool nuget:?package=Reactive.Wasm&version=3.0.1Install as a Cake Tool
👁 Build
👁 #yourfirstpr
👁 alternate text is missing from this package README image
👁 NuGet
👁 codecov
<br> <a href="https://github.com/reactiveui/reactiveui"> <img width="160" heigth="160" src="https://raw.githubusercontent.com/reactiveui/styleguide/master/logo/main.png"> </a> <br>
This package provides WebAssembly-specific implementations for System.Reactive, designed to be integrated into ReactiveUI and ReactiveUI.Uno projects to enable optimal reactive programming in WebAssembly environments. It provides platform-aware scheduler selection and WASM-optimized concurrency abstractions for cross-platform applications targeting Blazor WebAssembly and other WASM hosts.
To get started, install the following package into your WebAssembly project.
| Platform | NuGet |
|---|---|
| WebAssembly | 👁 NuGet |
Welcome to the System.Reactive.Wasm integration guide! This tutorial shows you how to integrate this package into ReactiveUI and ReactiveUI.Uno projects to enable optimal reactive programming across platforms, with special support for WebAssembly environments like Blazor WebAssembly.
The most common usage of System.Reactive.Wasm is not as a standalone library, but as an integration component that provides platform-aware scheduler selection for cross-platform ReactiveUI applications.
The primary integration scenario involves configuring ReactiveUI's scheduler selection to use appropriate schedulers based on the target platform.
Add the Reactive.Wasm package to your ReactiveUI project that targets WebAssembly:
<PackageReference Include="Reactive.Wasm" Version="[latest-version]" />
<PackageReference Include="ReactiveUI" Version="[latest-version]" />
Configure your dependency injection to select the appropriate scheduler based on the platform. This is the most common integration pattern:
using ReactiveUI;
using Microsoft.Extensions.DependencyInjection;
using System.Reactive.Concurrency;
public static void ConfigureServices(IServiceCollection services)
{
// Configure platform-aware scheduler selection
// WebAssembly does not support Threads for .NET5/.NET6+
_ = services
.AddSingleton<IScheduler>(static provider =>
{
return provider.GetRequiredService<Platform>() switch
{
Platform.WebAssembly => RxApp.MainThreadScheduler,
_ => RxApp.TaskpoolScheduler,
};
});
// Register your ViewModels and other services
services.AddTransient<MyViewModel>();
}
Create a simple platform detection service to identify WebAssembly environments:
public enum Platform
{
WebAssembly,
Desktop,
Mobile
}
public interface IPlatformService
{
Platform CurrentPlatform { get; }
}
public class PlatformService : IPlatformService
{
public Platform CurrentPlatform => DetectPlatform();
private static Platform DetectPlatform()
{
#if WEBASSEMBLY
return Platform.WebAssembly;
#elif ANDROID || IOS
return Platform.Mobile;
#else
return Platform.Desktop;
#endif
}
}
For Uno Platform projects using ReactiveUI, the integration follows a similar pattern with some Uno-specific considerations.
In your Uno Platform project, configure the scheduler selection in your App.xaml.cs:
using ReactiveUI;
using Microsoft.Extensions.DependencyInjection;
using System.Reactive.Concurrency;
public partial class App : Application
{
public App()
{
this.InitializeComponent();
ConfigureServices();
}
private void ConfigureServices()
{
var services = new ServiceCollection();
// Platform-aware scheduler configuration for Uno
services.AddSingleton<IScheduler>(provider =>
{
#if __WASM__
// WebAssembly platform uses MainThreadScheduler
return RxApp.MainThreadScheduler;
#else
// Other Uno platforms use TaskpoolScheduler
return RxApp.TaskpoolScheduler;
#endif
});
// Register ReactiveUI services
services.AddSingleton<IViewLocator, DefaultViewLocator>();
// Register your ViewModels
services.AddTransient<MainViewModel>();
}
}
Your ViewModels work seamlessly across all Uno platforms with the configured schedulers:
using ReactiveUI;
using System.Reactive;
using System.Reactive.Linq;
public class MainViewModel : ReactiveObject
{
private string _message = "Hello Uno!";
public string Message
{
get => _message;
set => this.RaiseAndSetIfChanged(ref _message, value);
}
public ReactiveCommand<Unit, Unit> UpdateMessageCommand { get; }
public MainViewModel()
{
UpdateMessageCommand = ReactiveCommand.CreateFromTask(async () =>
{
// This will use the appropriate scheduler based on platform
Message = $"Updated at {DateTime.Now:HH:mm:ss}";
// Demonstrate reactive stream that works across platforms
await Observable.Timer(TimeSpan.FromSeconds(1))
.Select(_ => $"Delayed update at {DateTime.Now:HH:mm:ss}")
.Do(msg => Message = msg);
});
}
}
The following sections cover advanced scenarios where you need direct access to WASM-specific reactive features. Most applications using ReactiveUI or ReactiveUI.Uno won't need these advanced techniques.
The WasmScheduler is specifically designed to work efficiently with the WebAssembly runtime, providing optimal scheduling for both immediate and delayed operations.
using System.Reactive.Concurrency;
public class SchedulerExample
{
public void DemonstrateWasmScheduler()
{
var scheduler = WasmScheduler.Default;
// Schedule immediate work
scheduler.Schedule(() => Console.WriteLine("Immediate work executed"));
// Schedule delayed work
scheduler.Schedule(TimeSpan.FromSeconds(2), () =>
Console.WriteLine("Delayed work executed after 2 seconds"));
// Schedule periodic work
var periodicWork = scheduler.SchedulePeriodic(TimeSpan.FromSeconds(1), () =>
Console.WriteLine($"Periodic work executed at {DateTime.Now:HH:mm:ss}"));
}
}
using System.Reactive.Linq;
using System.Reactive.Concurrency;
public class CustomSchedulingExample
{
public void CreateScheduledStream()
{
var wasmScheduler = WasmScheduler.Default;
// Create an observable that uses the WASM scheduler
var scheduledStream = Observable.Generate(
0, // Initial state
x => x < 10, // Continue condition
x => x + 1, // Iterator
x => $"Value: {x}", // Result selector
x => TimeSpan.FromMilliseconds(500), // Time selector
wasmScheduler) // Use WASM scheduler
.Subscribe(value => Console.WriteLine(value));
}
}
For scenarios where you need manual control over the reactive platform services, you can use the Platform Enlightenment Provider directly:
using System.Reactive.PlatformServices;
public static void Main(string[] args)
{
// Enable WASM-specific reactive extensions
#pragma warning disable CS0618 // Type or member is obsolete
PlatformEnlightenmentProvider.Current.EnableWasm();
#pragma warning restore CS0618 // Type or member is obsolete
// ... rest of your application initialization
}
WebAssembly has unique performance characteristics. Here are some best practices for reactive programming in WASM environments.
public class PerformanceOptimizedExample
{
public IObservable<string> CreateOptimizedStream(IObservable<int> source)
{
return source
.Where(x => x > 0) // Filter early
.Buffer(TimeSpan.FromMilliseconds(100)) // Batch operations
.Where(buffer => buffer.Count > 0) // Avoid empty batches
.Select(buffer => $"Processed {buffer.Count} items")
.DistinctUntilChanged() // Avoid duplicate notifications
.ObserveOn(WasmScheduler.Default); // Ensure WASM scheduling
}
}
using System.Reactive.Disposables;
public class MemoryEfficientExample : IDisposable
{
private readonly CompositeDisposable _disposables = new();
public void SetupReactiveStreams()
{
// Always dispose of subscriptions in WASM to prevent memory leaks
var subscription1 = Observable.Timer(TimeSpan.FromSeconds(1))
.Subscribe(x => Console.WriteLine($"Timer: {x}"));
var subscription2 = Observable.FromEvent<EventArgs>(
h => SomeEvent += h,
h => SomeEvent -= h)
.Subscribe(x => Console.WriteLine("Event received"));
// Add to composite disposable for easy cleanup
_disposables.Add(subscription1);
_disposables.Add(subscription2);
}
public event EventHandler<EventArgs>? SomeEvent;
public void Dispose()
{
_disposables.Dispose();
}
}
System.Reactive.Wasm works seamlessly with various WASM frameworks.
@page "/reactive-demo"
@using System.Reactive.Linq
@using System.Reactive.Subjects
@implements IDisposable
<h3>Reactive WASM Demo</h3>
<p>Current Time: @currentTime</p>
<p>Counter: @counter</p>
@code {
private string currentTime = "";
private int counter = 0;
private IDisposable? timeSubscription;
private IDisposable? counterSubscription;
protected override void OnInitialized()
{
// Create a time stream
timeSubscription = Observable.Timer(TimeSpan.Zero, TimeSpan.FromSeconds(1))
.Select(_ => DateTime.Now.ToString("HH:mm:ss"))
.Subscribe(time =>
{
currentTime = time;
InvokeAsync(StateHasChanged);
});
// Create a counter stream
counterSubscription = Observable.Timer(TimeSpan.Zero, TimeSpan.FromMilliseconds(100))
.Subscribe(tick =>
{
counter = (int)tick;
InvokeAsync(StateHasChanged);
});
}
public void Dispose()
{
timeSubscription?.Dispose();
counterSubscription?.Dispose();
}
}
This tutorial has covered the basics of getting started with System.Reactive.Wasm. You've learned how to set up your project, use the WASM scheduler, optimize performance, and integrate with WASM frameworks. From here, you can explore more advanced System.Reactive features, all optimized for WebAssembly environments.
We want to thank the following contributors and libraries that help make System.Reactive.Wasm possible:
The core team members, ReactiveUI contributors and contributors in the ecosystem do this open-source work in their free time. If you use System.Reactive.Wasm, a serious task, and you'd like us to invest more time on it, please donate. This project increases your income/productivity too. It makes development and applications faster and it reduces the required bandwidth.
This is how we use the donations:
If you have a question, please see if any discussions in our GitHub Discussions or GitHub issues have already answered it.
If you want to discuss something or just need help, here is our Slack room, where there are always individuals looking to help out!
Please do not open GitHub issues for support requests.
System.Reactive.Wasm is developed under an OSI-approved open source license, making it freely usable and distributable, even for commercial use.
If you want to submit pull requests please first open a GitHub issue to discuss. We are first time PR contributors friendly.
See Contribution Guidelines for further information how to contribute changes.
System.Reactive.Wasm is licensed under the MIT License.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 net5.0 was computed. net5.0-windows net5.0-windows was computed. net6.0 net6.0 was computed. net6.0-android net6.0-android was computed. net6.0-ios net6.0-ios was computed. net6.0-maccatalyst net6.0-maccatalyst was computed. net6.0-macos net6.0-macos was computed. net6.0-tvos net6.0-tvos was computed. net6.0-windows net6.0-windows was computed. net7.0 net7.0 was computed. net7.0-android net7.0-android was computed. net7.0-ios net7.0-ios was computed. net7.0-maccatalyst net7.0-maccatalyst was computed. net7.0-macos net7.0-macos was computed. net7.0-tvos net7.0-tvos was computed. net7.0-windows net7.0-windows was computed. net8.0 net8.0 is compatible. net8.0-android net8.0-android was computed. net8.0-browser net8.0-browser was computed. net8.0-ios net8.0-ios was computed. net8.0-maccatalyst net8.0-maccatalyst was computed. net8.0-macos net8.0-macos was computed. net8.0-tvos net8.0-tvos was computed. net8.0-windows net8.0-windows was computed. net9.0 net9.0 is compatible. net9.0-android net9.0-android was computed. net9.0-browser net9.0-browser was computed. net9.0-ios net9.0-ios was computed. net9.0-maccatalyst net9.0-maccatalyst was computed. net9.0-macos net9.0-macos was computed. net9.0-tvos net9.0-tvos was computed. net9.0-windows net9.0-windows was computed. net10.0 net10.0 was computed. net10.0-android net10.0-android was computed. net10.0-browser net10.0-browser was computed. net10.0-ios net10.0-ios was computed. net10.0-maccatalyst net10.0-maccatalyst was computed. net10.0-macos net10.0-macos was computed. net10.0-tvos net10.0-tvos was computed. net10.0-windows net10.0-windows was computed. |
| .NET Core | netcoreapp2.0 netcoreapp2.0 was computed. netcoreapp2.1 netcoreapp2.1 was computed. netcoreapp2.2 netcoreapp2.2 was computed. netcoreapp3.0 netcoreapp3.0 was computed. netcoreapp3.1 netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.0 netstandard2.0 is compatible. netstandard2.1 netstandard2.1 was computed. |
| .NET Framework | net461 net461 was computed. net462 net462 was computed. net463 net463 was computed. net47 net47 was computed. net471 net471 was computed. net472 net472 was computed. net48 net48 was computed. net481 net481 was computed. |
| MonoAndroid | monoandroid monoandroid was computed. |
| MonoMac | monomac monomac was computed. |
| MonoTouch | monotouch monotouch was computed. |
| Tizen | tizen40 tizen40 was computed. tizen60 tizen60 was computed. |
| Xamarin.iOS | xamarinios xamarinios was computed. |
| Xamarin.Mac | xamarinmac xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos xamarinwatchos was computed. |
Showing the top 4 NuGet packages that depend on Reactive.Wasm:
| Package | Downloads |
|---|---|
|
ReactiveUI.Blazor
Contains the ReactiveUI platform specific extensions for Blazor |
|
|
ReactiveUI.Uno
A MVVM framework that integrates with the Reactive Extensions for .NET to create elegant, testable User Interfaces that run on any mobile or desktop platform. Supports Xamarin.iOS, Xamarin.Android, Xamarin.Mac, Xamarin Forms, Xamarin.TVOS, Tizen, WPF, Windows Forms, Universal Windows Platform (UWP) and the Uno Platform. |
|
|
ReduxSimple.Wasm
Simple Stupid Redux Store using Reactive Extensions, and a stupid adjust for it work on Wasm |
|
|
H.ReactiveUI.Uno.WinUI
Contains the ReactiveUI platform specific extensions for Uno WinUI |
Showing the top 1 popular GitHub repositories that depend on Reactive.Wasm:
| Repository | Stars |
|---|---|
|
reactiveui/ReactiveUI
An advanced, composable, functional reactive model-view-viewmodel framework for all .NET platforms that is inspired by functional reactive programming. ReactiveUI allows you to abstract mutable state away from your user interfaces, express the idea around a feature in one readable place and improve the testability of your application.
|
| Version | Downloads | Last Updated |
|---|---|---|
| 3.0.1 | 60,881 | 9/8/2025 |
| 2.1.2 | 158,925 | 2/18/2024 |
| 2.1.1-ge9f08acb98 | 460 | 2/18/2024 |
| 1.2.2 | 891,261 | 1/19/2020 |
| 1.2.1 | 6,051 | 1/1/2020 |
| 1.0.1-preview.12 | 1,361 | 9/19/2019 |
| 1.0.1-preview.8 | 1,658 | 6/25/2019 |
| 1.0.1-preview.3 | 559 | 6/16/2019 |
| 1.0.1-preview.1 | 556 | 6/16/2019 |