Reactor.Community.ReactorFlow
0.1.0-preview.1
See the version list below for details.
dotnet add package Reactor.Community.ReactorFlow --version 0.1.0-preview.1
NuGet\Install-Package Reactor.Community.ReactorFlow -Version 0.1.0-preview.1
<PackageReference Include="Reactor.Community.ReactorFlow" Version="0.1.0-preview.1" />
<PackageVersion Include="Reactor.Community.ReactorFlow" Version="0.1.0-preview.1" />
<PackageReference Include="Reactor.Community.ReactorFlow" />
paket add Reactor.Community.ReactorFlow --version 0.1.0-preview.1
#r "nuget: Reactor.Community.ReactorFlow, 0.1.0-preview.1"
#:package Reactor.Community.ReactorFlow@0.1.0-preview.1
#addin nuget:?package=Reactor.Community.ReactorFlow&version=0.1.0-preview.1&prerelease
#tool nuget:?package=Reactor.Community.ReactorFlow&version=0.1.0-preview.1&prerelease
Reactor.Community.ReactorFlow
A declarative, node-based graph / canvas library for Microsoft.UI.Reactor, inspired by React Flow. If you build node editors, flow diagrams, pipelines, mind maps or whiteboards on the web with React Flow, ReactorFlow gives you the same mental model — nodes, edges, handles, a pan/zoom viewport, and opt-in chrome — natively in WinUI.
It is standalone: it draws its own edge paths (bezier / step / smooth-step / straight) and depends only on Microsoft.UI.Reactor and Microsoft.WindowsAppSDK. Nothing is tied to any particular application.
dotnet add package Reactor.Community.ReactorFlow
Hello, flow
using Reactor.Community.ReactorFlow;
using static Microsoft.UI.Reactor.Factories;
public sealed class MyBoard : Component
{
public override Element Render()
{
var (nodes, setNodes) = UseState<IReadOnlyList<ReactorFlowNode>>(new[]
{
new ReactorFlowNode("a", 80, 120, 160, 64, Data: "Source",
Ports: new[] { new ReactorFlowPort("out", ReactorFlowPosition.Right) }),
new ReactorFlowNode("b", 360, 120, 160, 64, Data: "Sink",
Ports: new[] { new ReactorFlowPort("in", ReactorFlowPosition.Left) }),
});
var edges = new[] { new ReactorFlowEdge("a-b", "a", "b", "out", "in", Label: "flow") };
return Component<ReactorFlow, ReactorFlowProps>(new ReactorFlowProps(
Nodes: nodes,
Edges: edges,
OnNodesChange: changes => setNodes(ReactorFlow.ApplyNodeChanges(changes, nodes)),
Background: ReactorFlow.Background(),
Overlays: new[]
{
ReactorFlow.MiniMap(),
ReactorFlow.Controls(),
}));
}
}
Concepts
ReactorFlow keeps React Flow's vocabulary so the migration is mostly mechanical:
| React Flow | ReactorFlow |
|---|---|
<ReactFlow nodes edges /> |
Component<ReactorFlow, ReactorFlowProps>(...) |
Node |
ReactorFlowNode (data-only record: id, position, size, type, data, ports) |
Edge |
ReactorFlowEdge (source/target + optional ports, kind, label, animated) |
Handle (Position.Left…) |
ReactorFlowPort on a node, or ReactorFlow.Handle(...) in custom content |
nodeTypes |
IReadOnlyDictionary<string, Func<ReactorFlowNodeContext, Element>> |
onConnect(connection) |
OnConnect(ReactorFlowConnection) |
onNodesChange / applyNodeChanges |
OnNodesChange / ReactorFlow.ApplyNodeChanges |
onEdgesChange / applyEdgeChanges |
OnEdgesChange / ReactorFlow.ApplyEdgeChanges |
<Background /> |
ReactorFlow.Background(variant, gap, size, color) |
<MiniMap /> |
ReactorFlow.MiniMap(corner, width, margin) |
<Controls /> |
ReactorFlow.Controls(corner, showZoom, showFitView, margin) |
<Panel position> |
ReactorFlow.Panel(corner, content, margin) |
fitView() |
ReactorFlow.FitView(...), or the Fit button in Controls |
Nodes are data; renderers are components
A node is a plain record. How it looks is decided by a node type renderer — an Element factory keyed by ReactorFlowNode.Type. Because a renderer returns any Element, a node can be a full Reactor component with its own hooks and local state:
var nodeTypes = new Dictionary<string, Func<ReactorFlowNodeContext, Element>>
{
["counter"] = ctx => Component<CounterNode, CounterNodeProps>(new(ctx)),
};
Everything is opt-in
There is no default chrome. A bare ReactorFlow is just nodes, edges and a pan/zoom pane. Add Background, MiniMap, Controls or arbitrary Panel content only when you want them — pass them via Background: (bottom layer) and Overlays: (corner-anchored top layer).
Handles / ports
Attach ports to a node via ReactorFlowNode.Ports (one per side, or several with Alignment), or place ReactorFlow.Handle(position) inside custom node content. When OnConnect is supplied, dragging from a port draws a live connection and snaps to the nearest target port within ReactorFlowOptions.ConnectThreshold.
Edges
Edges are drawn as native PathGeometry — no external connector library:
ReactorFlowEdgeKind.Default— cubic bezierReactorFlowEdgeKind.SmoothStep— orthogonal with rounded cornersReactorFlowEdgeKind.Step— orthogonal, square cornersReactorFlowEdgeKind.Straight— direct line
Each edge supports a Label, a Color, StrokeWidth, and Animated marching-ants. Only animated edges re-render on the animation tick.
Options
ReactorFlowOptions controls zoom limits, pan/zoom gestures, handle sizes, corner radius and the connect snap threshold. Pass it via ReactorFlowProps.Options.
Sample
The sample app is a self-contained board with four node types (including an interactive stateful counter node), ports on all four sides, labeled / smooth-step / animated edges, drag-to-connect, pan/zoom, and the Background / MiniMap / Controls / Panel chrome.
dotnet run --project samples/Reactor.Community.ReactorFlow.Sample
License
MIT © 2026 Reactor Community
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0-windows10.0.26100 is compatible. |
-
net10.0-windows10.0.26100
- Microsoft.UI.Reactor (>= 0.1.0-preview.11)
- Microsoft.WindowsAppSDK (>= 2.2.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 0.4.0-preview.2 | 36 | 7/2/2026 |
| 0.4.0-preview.1 | 38 | 7/2/2026 |
| 0.1.0-preview.1 | 36 | 7/2/2026 |