Ranvier 0.1.1-preview.1

This is a prerelease version of Ranvier.
dotnet add package Ranvier --version 0.1.1-preview.1
                    
NuGet\Install-Package Ranvier -Version 0.1.1-preview.1
                    
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="Ranvier" Version="0.1.1-preview.1" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Ranvier" Version="0.1.1-preview.1" />
                    
Directory.Packages.props
<PackageReference Include="Ranvier" />
                    
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 Ranvier --version 0.1.1-preview.1
                    
#r "nuget: Ranvier, 0.1.1-preview.1"
                    
#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 Ranvier@0.1.1-preview.1
                    
#: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=Ranvier&version=0.1.1-preview.1&prerelease
                    
Install as a Cake Addin
#tool nuget:?package=Ranvier&version=0.1.1-preview.1&prerelease
                    
Install as a Cake Tool

Ranvier

Fine-grained reactive computation for .NET and Fable.

Preview. Ranvier is pre-release. Its APIs may change before the first release.

Ranvier connects signals, memos and effects in a reactive graph. Signals hold writable state; memos derive values and recompute on demand after their inputs change; effects run side effects after changes. Async sources carry an explicit Pending state, and boundaries handle pending or failed reads.

open Ranvier

use graph = new Graph ()

graph.Run (fun () ->
    let count = createSignal 1
    let doubled = createMemo (fun _ -> count.Value * 2)
    createEffect (fun () -> printfn "doubled = %d" doubled.Value)
    count.Value <- 5)

C# projects reference Ranvier.CSharp, which adds delegate-based factories and extension methods.

Targets

net10.0 and netstandard2.1. Applications on .NET 8 and .NET 9 use the netstandard2.1 build.

Package builds from this source include F# sources for Fable's JavaScript target. The same core APIs support signals, memos, effects, bindings and collections on both targets; see the Fable guide.

Fixed-dependency bindings and ownership

bindSignal source target write and bindMemo source target write copy one source into an external target in the flush. The writer receives the target and current value, runs untracked and must not create reactive nodes. A pending or failed memo leaves the target unchanged; an equal source value does not write again. Both factories return unit and attach to the current owner. Use a memo before bindMemo to derive a target value, or an effect for work with dynamic dependencies.

Owners dispose children and cleanups together in reverse acquisition order. A cleanup registered after a child is created runs before that child is disposed, both on disposal and before a run's owned resources are replaced. See Bindings and Cleanup.

Keyed row factories

createProjectionWithOptions ProjectionOptions.CreateFirst keyOf factory source creates added rows before retiring removed rows. If a new factory throws, the pass disposes its additions and keeps the previously applied rows, items and keys until a source change retries the pass.

createProjectionOnce options keyOf factory source stores one factory result per key without a row memo. It suits a view object whose factory creates its own bindings. Key readers are supported; value readers, AsObservableCollection and projection view/aggregate operators are not. Use createProjectionWith when those consumers need reactive row values. See Projections.

Per-node equality

Ordinary factories use GraphOptions.Equality. To override a node's value cutoff, supply a typed IEqualityComparer<T>:

let name = createSignalWithComparer System.StringComparer.OrdinalIgnoreCase "Ada"
let label = createMemoWithComparer System.StringComparer.OrdinalIgnoreCase (fun _ -> name.Value.Trim())

The override applies to that node. Other nodes continue using the graph policy. A signal keeps its current value when the comparer treats a write as equal. A memo caches its computed result but suppresses downstream work when it compares equal. Pending, failed, waiting and caught-error state changes still propagate.

The opt-in factories are createSignalWithComparer, createMemoWithComparer, createOwningMemoWithComparer, createEffectOnWithComparer, createSuspenseWithComparer, createErrorBoundaryWithComparer and createBoundaryWithComparer. Their ownership, purity and previous-value rules match the ordinary factories. Null comparers are rejected at construction. A comparer exception leaves a signal unchanged and reaches its writer; on a computed node it fails the node using its existing error handling. A boundary's recovery function handles body errors, so a comparer error fails the boundary directly.

Comparers are selected once at construction. Async sources and async memos retain their completion/state notifications, and collection APIs retain their graph-policy cutoffs.

The C# facade adds comparer overloads, for example Reactive.Signal("Ada", StringComparer.OrdinalIgnoreCase) and Reactive.Memo(() => name.Value.Trim(), StringComparer.OrdinalIgnoreCase).

Editable collections and change readers

let items = createKeyedCollection (fun (id, _) -> id)
items.Edit(fun edit ->
    edit.AddOrUpdate(1, "write")
    edit.AddOrUpdate(2, "test"))
let titles = items.Rows |> Projection.map snd
use reader = titles.NewValueReader ()
reader.Read () |> ignore // initial reset
items.AddOrUpdate(2, "retest")
let delta = reader.Read () // Changed for key 2

Reactive.KeyedCollection<T, K>(keyOf) is the C# factory. Rows supports the existing map/filter/sort/group/aggregate operators. Updating a live key writes its value directly; it preserves the key array and avoids scanning an input collection. New keys append. Removing and re-adding a key creates a new row, reported as Replaced to a reader that saw the old row. Removal searches insertion order in O(N); membership passes copy key order. Edit batches synchronous writes and retains applied edits if its callback throws.

NewKeyReader() reports membership and order. NewValueReader() also reports Changed for unequal settled row values under the graph policy. Each reader has an independent bounded cursor; the first read and overflow return a reset. Deltas are coalesced refresh hints containing keys, rather than value snapshots or a history of every intermediate write. Read current values through the projection and handle pending/error states there.

Value readers share observation and accepted values while any value reader lives. Initial observation evaluates every visible row; later value-only pulls evaluate suspect rows. Pending or failed rows retain their last settled value, and status changes alone do not produce Changed. Dispose readers to release observation. The .NET observable collection adapter uses this cache to update changed rows without polling every row.

Map membership consumes upstream key deltas. Filters, sorts, grouping and some aggregate membership paths still scan keys; this is a foundation for incremental collections, with explicit costs for membership and order.

Tracing

Ranvier.Traced is the same assembly, namespaces and version built with the per-graph event log and its queries. Reference it in place of Ranvier for development builds; see Tracing.

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 was computed.  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 was computed.  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 netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.1 is compatible. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen 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 (6)

Showing the top 5 NuGet packages that depend on Ranvier:

Package Downloads
Ranvier.View

Template components for Ranvier: typed templates, view sugar, keyed lists, arms and boundaries, with server HTML rendering on .NET and under Fable.

Ranvier.Elmish

An Elmish-style model-view-update bridge for Ranvier: a model held in a signal, updated by dispatched messages and read through selector memos.

Fable.Ranvier.Anime

Typed anime.js 4.5 bindings for Fable, with Ranvier integration: parameters as constructors with named optional arguments, and per-feature imports.

Ranvier.CSharp

C# entry points for Ranvier: delegate-based factories and extension methods.

Ranvier.Query

Typed reactive queries and mutation reconciliation for partially loaded application data.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
0.1.1-preview.1 1,416 10/28/2026
0.1.0-preview.7 168 10/26/2026
0.1.0-preview.6 81 10/21/2026
0.1.0-preview.5 89 10/4/2026
0.1.0-preview.4 78 10/3/2026
0.1.0-preview.3 72 9/30/2026
0.1.0-preview.2 70 9/30/2026
0.1.0-preview.1 70 9/29/2026

Preview release. The API may change before 1.0.