dioxus-flow
A node graph library for Dioxus, inspired by react-flow. You get a pannable, zoomable canvas with draggable nodes, connectable handles, animated edges, and automatic layout — and you can render nodes and edges with your own components.

The demo app: custom card nodes, edge labels, an animated edge, a custom-styled
edge, auto layout, minimap, and controls. Run it with cd demo && dx serve.
Features
- Interactive canvas — drag or two-finger scroll to pan, pinch to zoom, click or shift-click to select, drag several nodes at once, press Delete to remove.
- Connections — drag from one handle to another to create an edge. The preview line snaps to nearby handles.
- Edges — bezier, straight, or smooth-step. Add labels, arrowheads at
either end, and an
animatedmarching-dashes mode. - Seat anchoring —
Flow { anchor: AnchorMode::Seats }packs edge endpoints into discrete seats around each node's rounded rim (deterministic, crossing-free where possible), drawn with rim-aware curves and beads. The solver is also usable headlessly via theportsmodule. - Auto layout — a built-in layered layout engine, in any of four directions. Nodes and the viewport animate smoothly to their new places.
- Custom everything — render node content with any Dioxus component (Tailwind works great), place handles anywhere, or draw your own edge SVG.
- Batteries included —
Background,Controls, andMiniMapoverlays, plususe_flow()to build your own. - Keyboard & accessibility — nodes are focusable and movable with arrow
keys, with ARIA labels and
prefers-reduced-motionsupport. - Fast — careful reactive scoping keeps pan, zoom, and drag at 60fps with 1000 nodes (release build).
- Dark mode out of the box, themable with CSS variables.
Quickstart
use *;
use *;
The Flow fills its parent, so give the parent a size. Nodes and edges are
plain signals that you own: the flow updates them when the user drags,
connects, or deletes, and you can change them yourself at any time.
Custom nodes
Pass a node_view function to render nodes your way. It receives every node;
match on node_type and return any element. Put Handles wherever you want —
edges attach to them.
Flow
Node<T> is generic over your own data (Node<()> by default); build one
with Node::with_data(id, label, pos, data). A node can have several handles:
give each an id and an offset, and point at them from
Edge::source_handle / Edge::target_handle.
Custom edges
Most styling needs no custom view — use the builder:
new
.kind
.label
.style
.marker_end
For full control, pass an edge_view function. You get the resolved anchor
points and the default path, so you can restyle without redoing the math:
Flow
Auto layout and programmatic control
Create a FlowHandle to drive the flow from outside:
let flow = ;
rsx!
auto_layout animates nodes and the viewport together; any user interaction
cancels the animation cleanly. Inside the flow (custom overlays, nodes,
controls), use_flow() gives you the same API: the viewport signal,
fit_view, zoom_by, center_on, coordinate conversion, and node geometry.
Events
| Prop | Fires when |
|---|---|
on_connect |
the user completes a connection (if absent, the edge is added for you) |
on_connect_start / on_connect_end |
a connection drag leaves a handle / ends anywhere — on_connect_end carries the release point and connection: None for a drop on empty canvas, the hook for creating the node there |
is_valid_connection |
(a callback, not an event) your say over which connections may complete; failing targets are never offered as snaps |
on_node_drag_start / on_node_drag_stop |
a node drag really begins (past drag_threshold, the undo-snapshot moment) / ends with final positions (the snap-and-persist moment) |
on_delete |
Delete/Backspace with a selection (if absent, it's deleted for you) — call flow.delete_selected() to proceed, e.g. after saving an undo snapshot |
on_node_click / on_edge_click |
pointer down on a node / edge |
on_pane_click |
click on empty canvas (in flow coordinates) |
Theming
Override the CSS variables on .dioxus-flow or any ancestor:
}
Dark mode follows prefers-color-scheme automatically.
Development
The repo is a workspace: dioxus-flow/ is the library, demo/ is the demo
app. The Nix flake provides everything (Rust with the wasm target, dx,
tailwindcss, wasm-opt); CI runs fmt, clippy, tests, and a wasm check
through the same flake.
&&
Two tips:
- For release builds, pass
--debug-symbols false— the nixpkgswasm-optis newer than the one dx pins and crashes on the debug info dx keeps by default:dx build --release --debug-symbols false. - The demo doubles as a performance harness:
?stress=1000replaces the showcase graph with a 1000-node grid for profiling.
Roadmap
- Box selection, edge reconnection
- Sub-flows / node grouping
- Viewport-culled rendering for very large graphs