egui-xyflow evaluation — DO NOT WRAP (yet)
Date: 2026-06-12 Subject: https://github.com/avinkrisv/egui-xyflow (crate egui_xyflow) Verdict: Do not wrap now. Hard egui-version incompatibility. Revisit when egui-xyflow ships a release built against egui 0.34 (see "Unblock condition").
1. Upstream facts
| Field | Value |
| Crate name | egui_xyflow |
| Newest published version | 0.4.3 (crates.io, published 2026-05-06) |
| All versions | 0.2.0, 0.2.1, 0.3.0, 0.4.0, 0.4.1, 0.4.2, 0.4.3 |
| egui target | 0.31 (egui = "0.31", emath = "0.31", epaint = "0.31") |
| License | MIT (facett is MIT OR Apache-2.0 — MIT alone is compatible to consume) |
| Edition / MSRV | 2024 / Rust 1.85 |
| Other deps | smallvec, log, optional serde (default feature on) |
| Dev deps | eframe = 0.31, env_logger, serde_json |
| Examples | 15 example projects (basic flows → hierarchical edge bundling, stress tests) |
API surface (from README)
Builder-pattern nodes/edges, trait-based custom widgets, an event-returning canvas, and a fat config struct for theming:
// Node
Node::builder("my-node")
.position(egui::pos2(200.0, 150.0))
.data("Hello".to_string())
.handle(NodeHandle::source(Position::Right))
.size(180.0, 60.0)
.build()
// Edge
Edge::builder("e2", "a", "b")
.edge_type(EdgeType::SmoothStep)
.color(egui::Color32::from_rgb(59, 130, 246))
.stroke_width(3.0)
.animated(true)
.label("1,284 rows/s")
// Render + interaction
let events: FlowEvents = FlowCanvas::show(ui); // connections, clicks, selection, viewport
- Custom rendering: implement
NodeWidget/EdgeWidget;DefaultNodeWidgetis provided. - Interaction:
FlowCanvas::show(ui)returnsFlowEvents(connection-created, click, selection-change, viewport-change). This is a real editor (drag, connect handles, pan/zoom). - Theming:
FlowConfigwith 60+ options (colors, snap-to-grid, zoom bounds, edge types, background patterns).
This is genuinely the "React Flow for egui" niche: an interactive, editable flow graph with draggable nodes and user-drawn connections — not just a render-only view.
2. Compatibility verdict vs facett (egui 0.34)
INCOMPATIBLE — will not type-unify.
- facett pins
egui = "0.34"workspace-wide (Cargo.toml [workspace.dependencies]), e.g.facett-plotusesegui_plot = "0.35"which is the egui-0.34-aligned line. - egui-xyflow 0.4.3 (the newest and only current release) depends on
egui/emath/epaint = "0.31"— two minor majors behind. - egui makes breaking changes every minor; 0.31 and 0.34
Color32/Ui/Painter/Pos2types are distinct, non-interchangeable types in the dependency graph. Cargo would pull both egui 0.31 and 0.34 into the tree, and any value crossing the boundary (aUi, aFlowEvents) would be a type-mismatch at the wrap seam. You cannot pass facett's&mut egui::Ui(0.34) intoFlowCanvas::show(expects 0.34? no — 0.31). - Therefore a
facett-flowwrapper implementingFacet::ui(&mut self, ui: &mut egui::Ui)cannot forwarduiinto egui-xyflow. No wrap is possible without a fork/backport.
No broken dependency was added to the workspace. Cargo.toml members, the umbrella facett crate, and Cargo.lock are untouched.
3. egui-xyflow vs snarl vs facett-graph — when to use which
Three node/edge tools are now in play around facett/nornir:
| Tool | egui | Nature | Best for |
| facett-graph / facett-graph3d (in-house) | 0.34 ✅ | Render-only Scene (nodes+edges), circular/force layout, CPU painter (wgpu path planned) |
Read-only visualisation of relationships — knowledge graphs, callgraphs, dependency graphs. Source-agnostic, headless-testable via Facet/state_json. The default for "show me this graph." |
| egui-snarl (used in nornir Funnel) | tracks egui closely (0.34-compatible line exists) | Interactive node editor, typed pins, in/out wires, viewer trait | Node-wiring UIs where the user builds a graph: nornir's Funnel (ideas→plan), shader/dataflow editors. Mature, egui-version-current, already a known quantity in this stack. |
| egui-xyflow | 0.31 only ❌ | Interactive flow editor, React-Flow ergonomics, animated edges, handles, snap-grid, 60+ theming knobs | Admin / workflow / pipeline builders with a polished "flow" aesthetic (animated edges, labels like "1,284 rows/s", edge bundling). Strongest UX of the three if the version caught up. |
Recommendation:
- For read-only graph viz (the bulk of korp/nornir needs today): stay on facett-graph / facett-graph3d. They're in-house, 0.34-native, headless-testable, and have the wgpu fast-path roadmap.
- For interactive node-wiring editors right now: use egui-snarl — it is already egui-current and battle-tested in nornir's Funnel. If facett ever wants a generic "node editor" facet, wrap snarl, not xyflow.
- egui-xyflow is the most visually polished flow-editor of the three and the natural pick for a future "pipeline/workflow builder" facet (animated dataflow edges, throughput labels — exactly the knut/skade pipeline-viewer aesthetic) — but only once it targets egui 0.34. Until then snarl covers the same need without a version conflict.
4. Unblock condition (when to revisit)
Revisit and scaffold facett-flow when egui-xyflow publishes a release whose egui/emath/epaint dependency is 0.34 (or whatever facett's egui is at the time).
Concretely, before re-attempting:
cargo search egui_xyflow(or check crates.io) for a version> 0.4.3.- Confirm its
Cargo.tomlhasegui = "0.34"(raw URL:https://raw.githubusercontent.com/avinkrisv/egui-xyflow/master/Cargo.toml). - If yes: scaffold a thin
facett-flowcrate mirroringfacett-plot's shape — aFlowViewimplementingfacett-core::Facet(title/ui/state_json), a tiny node/edge demo, add to workspacemembers+ umbrellafacettre-export (pub use facett_flow as flow;), and a smoke test. Map xyflow'sFlowEventsselection/click state intostate_jsonfor headless assertions.
Alternative (only if there's strong demand and xyflow stays stale): fork/backport xyflow 0.4.x to egui 0.34 — but that is a real maintenance burden and not worth it while egui-snarl already serves the interactive-editor need at 0.34.