# ReactiveUI 24: a cross-platform MVVM framework built on functional reactive programming

> ReactiveUI moves mutable state out of the view and into view models expressed as observable pipelines. Version 24 splits the framework into two interchangeable distributions and a new Primitives engine, which changes the public reactive types you write against.

**reactiveui/ReactiveUI** — A composable, cross-platform MVVM framework for .NET inspired by functional reactive programming. It moves mutable state out of the user interface, keeps each feature's logic in one readable place, and makes applications easier to test. Supports WPF, WinForms, WinUI, .NET MAUI, Avalonia, Uno Platform, Blazor and Android.

- Repository: https://github.com/reactiveui/ReactiveUI
- Website: https://www.reactiveui.net
- Stars: 8,539 · Forks: 1,151
- Language: C#
- License: MIT
- Published: 2026-09-21 · Updated: 2026-09-21 · Language: en
- Canonical page: https://hysenlabs.com/projects/reactiveui-reactiveui

## The mutable state problem ReactiveUI targets

A typical .NET client app spreads feature logic across event handlers, property setters, and code-behind that touches controls directly. That arrangement is hard to test because the logic only runs when a view exists. ReactiveUI's stated goal is to abstract mutable state away from the user interface and express a feature in one readable place. The unit of that place is the view model, and the framework supplies the plumbing that keeps the view model in sync with the view without the view model knowing which UI toolkit is underneath.

The audience is .NET developers building the same feature on more than one UI stack. The README lists WPF, WinUI, MAUI, Windows Forms, AndroidX, Blazor, Uno Platform, and Avalonia packages, plus a .NET Standard core. If you only ever ship one desktop app and your logic is already testable, the framework's reactive scheduler model is overhead you would be paying for nothing.

## How the observable pipeline replaces event handlers

The mechanism is composition over callbacks. Instead of assigning a handler and mutating a field inside it, you build a pipeline: a source (a property, a command, a timer) is projected and filtered, then written into a target property. The README describes the framework as inspired by functional reactive programming, and the public API reflects that. `WhenAnyValue` observes a property and emits its values; `ToProperty` writes those emissions into a view model property. Both are named in the release notes for version 24 as the hottest MVVM paths, which tells you where the framework expects most of your code to live.

Routing is the second layer. `RoutingState`, `IScreen`, and `RoutedViewHost` stay in the main package and handle navigation between view models. In version 24 the DynamicData change-set routing, collection, and auto-persist helpers moved out into a separate `ReactiveUI.Routing` package, so the core no longer depends on DynamicData. If your app uses those extensions, you add the package; if it does not, you get a smaller dependency closure. That is a deliberate trade: existing code that relied on the helpers being present transitively will need an explicit reference.

## Choosing between the Primitives and System.Reactive distributions

Version 24 ships two distributions with an identical public API, both on the same ReactiveUI.Primitives engine and the same custom schedulers. The difference is which reactive interop types appear in your public surface. The default packages (ReactiveUI, ReactiveUI.Wpf, ReactiveUI.WinForms, ReactiveUI.WinUI, ReactiveUI.Maui, ReactiveUI.Blazor, ReactiveUI.AndroidX and their siblings) expose `RxVoid`, `ISequencer`, and `Signal<T>`. The `.Reactive` family (ReactiveUI.Reactive, ReactiveUI.Wpf.Reactive, and so on) exposes `Unit`, `IScheduler`, and `Subject<T>` instead.

The README is explicit that the `.Reactive` family is not the old ReactiveUI. It runs on the same engine and the same schedulers, and only surfaces the System.Reactive types so existing code composes. The default distribution drops the System.Reactive dependency for a smaller closure and what the README calls a better trimming and AOT story. The performance figures in the README are micro-benchmarks from the project itself: roughly 3 to 4 times faster on `WhenAnyValue` and `ToProperty` subscribe and emit, with 5 to 13 times less allocation, including `WhenAnyValue` emit dropping from about 6.8 MB to about 0.5 MB per run and `ToProperty` construction from about 7.3 microseconds to about 1.0 microsecond. Treat those as the maintainers' numbers on their own benchmarks, not as a guarantee for your workload.

The practical consequence is a type migration. If you take the default packages, `IScheduler` becomes `ISequencer`, `System.Reactive.Unit` becomes `RxVoid`, and `Subject<T>` and `BehaviorSubject<T>` become `Signal<T>` and `BehaviorSignal<T>`. The zero-source-change path is to reference the matching `.Reactive` packages and keep the names you already use.

## Installing ReactiveUI and enabling the analyzers

The README points to the installation page on reactiveui.net and lists the NuGet packages per platform. Some platform-specific packages are required, and the README warns that an app will not perform as expected until the packages are installed properly. For a WPF app the README's table names ReactiveUI.WPF, and for the System.Reactive flavor the corresponding entry is ReactiveUI.Wpf.Reactive. The installation page is where the README sends you for the exact commands, so this article does not reproduce a CLI line it cannot quote.

One opt-in is worth knowing about before your first build. The ReactiveUI packages reference ReactiveUI.Primitives with `ExcludeAssets="analyzers"`, so the analyzers that ship inside ReactiveUI.Primitives do not flow into your project and will not run against your code just because you installed ReactiveUI. The README states this is deliberate: the maintainers do not impose their analyzers on downstream consumers. To enable them, add a direct reference to ReactiveUI.Primitives without excluding the analyzer assets. The README gives exactly this snippet:

```xml
<PackageReference Include="ReactiveUI.Primitives" Version="x.y.z" />
```

After that, a first real use is a view model property derived from another property through `WhenAnyValue` and `ToProperty`, which is the pattern the version 24 benchmarks measure. The README does not walk through a complete sample in the text available here; it links to the samples page and to a book by a former maintainer for that.

## Where ReactiveUI is the wrong tool

The cost is conceptual, and it is front-loaded. You have to internalize schedulers, observable lifetimes, and the difference between a cold and hot sequence before the code stops surprising you. A team that wants property-change notification and a command implementation will find a smaller MVVM helper library easier to onboard, because there is no scheduler to configure and no pipeline to reason about.

The second limitation is the version 24 type change. The default distribution is the one the README frames as the new lighter default, but adopting it means your public API now names `ISequencer`, `RxVoid`, and `Signal<T>`. Code that other assemblies compile against will need those assemblies updated too. The `.Reactive` packages avoid the source change, but they keep the System.Reactive dependency, which is exactly the closure the default distribution was built to drop. You cannot have both the smaller closure and the unchanged type names.

Third, the README does not document rollback. There is no stated procedure for reverting a project from the default distribution back to `.Reactive`, or the reverse, beyond swapping package references. If you are mid-migration and something breaks, the repository text available here does not tell you what to do.

## ReactiveUI compared with CommunityToolkit.Mvvm

The comparison that comes up most is against CommunityToolkit.Mvvm. The difference in approach is the execution model. CommunityToolkit.Mvvm is source-generator driven and imperative: you annotate a field and get a property that raises change notification, and you write methods that mutate state directly. ReactiveUI is pipeline driven: state changes are values flowing through observable sequences, and the framework provides the operators to combine, filter, and project them.

That makes ReactiveUI more expressive when a feature genuinely depends on several asynchronous sources at once, and it makes it heavier when a feature is a button that sets a flag. The two are not mutually exclusive in principle, since both are NuGet packages, but mixing them in one view model means carrying two mental models and two sets of conventions. Prism is the other name that appears in searches; it is a modular application framework with its own regions and modules, so the overlap is in navigation rather than in state composition. The README does not compare ReactiveUI to either project, so any deeper claim about them would be speculation.

## Licence, release cadence and upgrade cost

ReactiveUI is MIT licensed. That permits commercial and closed-source use and modification, and it requires the copyright notice and permission notice to be preserved. This is a description of the licence text, not legal advice; check the LICENSE file in the repository for the exact wording that binds you.

On cadence, the release notes show 24.0.0 on 2026-07-26, 24.1.0 on 2026-08-02, and 24.2.0 on 2026-09-04, with the last push to the default branch on 2026-09-21. Three minor releases inside roughly six weeks of a major version means the 24 line is still settling. Plan for package-reference churn rather than API churn if you stay on `.Reactive`, and for both if you adopt the default distribution and the Primitives types.

The upgrade cost has two distinct parts. The mechanical part is swapping package IDs and, for the default distribution, renaming `IScheduler`, `Unit`, and `Subject<T>` at every boundary. The structural part is the move of DynamicData routing and collection helpers into `ReactiveUI.Routing`, which changes what a project reference pulls in. Neither is documented with a step-by-step migration guide in the README text available here.

## Conclusion

ReactiveUI fits teams that already think in observables and want view model logic expressed as one composable pipeline across several UI platforms, and it fits greenfield projects that can start on the default Primitives distribution. It does not fit teams that want a small, imperative MVVM helper and no scheduler model to learn, and it does not fit codebases that cannot absorb a public type change from IScheduler to ISequencer. Verify two things before committing: whether the platform package for your target exists in the table in the README, and whether you need ReactiveUI.Routing for the DynamicData change-set helpers, since core no longer carries them.

## FAQ

### What is ReactiveUI?

It is a composable, cross-platform model-view-viewmodel framework for .NET platforms, inspired by functional reactive programming. Its stated aim is to abstract mutable state away from user interfaces, keep a feature's logic in one readable place, and improve testability.

### ReactiveUI vs MVVM Toolkit: what is the difference?

The README does not compare the two projects. The visible difference in approach is that ReactiveUI expresses state as observable pipelines with a scheduler model, while it describes itself as a framework for all .NET platforms with per-platform packages such as ReactiveUI.WPF and ReactiveUI.Maui.

### ReactiveUI vs CommunityToolkit.Mvvm: which should I pick?

The repository text does not make this comparison. ReactiveUI's own description centers on functional reactive programming and moving mutable state out of the UI, and it ships separate packages per platform plus optional analyzers that are excluded by default.

### ReactiveUI vs Prism: how do they differ?

The README does not discuss Prism. What it does document is ReactiveUI's own routing layer: RoutingState, IScreen and RoutedViewHost stay in the main package, while the DynamicData change-set routing and collection helpers moved to ReactiveUI.Routing in version 24.

## Sources

- [License: MIT](https://github.com/reactiveui/ReactiveUI/blob/main/LICENSE)
- [Project website](https://www.reactiveui.net)
- [reactiveui/ReactiveUI on GitHub](https://github.com/reactiveui/ReactiveUI)
- [README](https://github.com/reactiveui/ReactiveUI/blob/main/README.md)
- [Releases](https://github.com/reactiveui/ReactiveUI/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/reactiveui-reactiveui
