Review Date: 2026-01-13 Reviewer: Claude (GLM-4.7) Project: makepad-flow v0.1.0
makepad-flow is a promising Rust-based flow editor widget library built on Makepad with approximately 30% feature parity with React Flow. The project demonstrates solid foundational work with clean architecture and custom shaders, but has significant gaps for production use—particularly for multi-port dataflow visualization.
Overall Assessment: Foundationally sound but incomplete for production use cases.
A flow/node editor widget for Makepad, designed to create interactive node-based UIs similar to React Flow (xyflow).
makepad-flow/
├── crates/makepad-flow/ # Main library crate
│ ├── src/
│ │ ├── lib.rs # Library entry point (14 lines)
│ │ └── flow_canvas.rs # Core canvas implementation (2,434 lines)
├── examples/
│ ├── flow-editor/ # Interactive flow editor (150 lines)
│ └── dora-viewer/ # Dora dataflow visualizer (306 lines)
├── src/ # Legacy duplicate code
├── ROADMAP.md # Feature implementation plan
├── API_GAPS.md # Comparison with React Flow
└── DATAFLOW_GAPS.md # Dataflow visualization analysis
makepad-widgets(git:https://github.com/makepad/makepad, branch:rik)- Uses Makepad's live design system and custom shaders
| Aspect | Assessment |
|---|---|
| Single-file architecture | Core FlowCanvas widget in 2,434 well-organized lines |
| Custom SDF shaders | Elegant signed-distance-field rendering for smooth rounded corners |
| Event-driven design | Proper use of Makepad's action system |
| Type safety | Strong Rust enums for shapes, categories, styles |
| Undo/redo | History stack implementation with Ctrl+Z/Y |
| Inline comments | Well-documented implementation |
| Modular design | Separate concerns for canvas, nodes, edges |
| Aspect | Issue |
|---|---|
| No README | Critical missing documentation for onboarding |
| Limited API surface | Only exports FlowCanvas widget, no utility modules |
| Tight coupling | Data structures directly tied to widget implementation |
| Code duplication | Legacy src/flow/ directory duplicates crate functionality |
| No trait abstractions | Can't customize node/edge renderers |
| Hardcoded styling | Colors, sizes embedded in shaders |
| Feature | Implementation Details |
|---|---|
| Canvas pan/zoom | Shift+drag pan, scroll wheel zoom (0.25x-4x) |
| Node selection | Single click, multi-selection (Shift+click, drag box) |
| Node shapes | 5 types: RoundedRect, DoubleRoundedRect, Rectangle, Round, Diamond |
| Node categories | 6 types with color coding (MaaS, TTS, Bridge, Controller, MoFA, Segmenter) |
| Bezier edges | With labels, markers, styles (solid/dashed/dotted) |
| Animations | Flow particles on edges with timer-based updates |
| Keyboard shortcuts | Delete, Ctrl+A (select all), Escape (deselect), Ctrl+Z/Y (undo/redo) |
| Context menus | Right-click on nodes/edges |
| Commands | AddNode, Delete, FitView, Clear, SetLineStyle, SetLineWidth |
| Edge markers | Arrow heads at endpoints |
| Category | Missing Feature | Impact |
|---|---|---|
| Multi-port nodes | Multiple inputs/outputs per node | BLOCKING for dataflow use cases |
| Event callbacks | onNodesChange, onConnect, onSelectionChange | No integration hooks |
| Persistence | Export/import JSON | Can't save/load graphs |
| MiniMap | Canvas overview widget | Poor large-graph UX |
| Controls panel | Zoom in/out/fit buttons | Accessibility issue |
| Background grid | Dot/line patterns, snap-to-grid | No visual reference |
| Node resizing | Drag handles to resize | Fixed node dimensions |
| Edge reconnection | Drag existing edge to new target | Rigid editing |
| Connection validation | Validate connections before creating | Invalid connections possible |
| Copy/paste | Duplicate selected nodes/edges | Poor productivity |
| Parent-child grouping | Nested node hierarchies | No organization |
| Graph utilities | getIncomers, getOutgoers, graph analysis | No traversal helpers |
| Theming | Light/dark mode, CSS variables | Fixed dark appearance |
| Auto-layout | Automatic node arrangement | Manual positioning only |
// Simple drop-in usage
use makepad_flow::*;
live_design! {
canvas = <FlowCanvas> {}
}
// Command-based interaction
cx.action(FlowCanvasCommand::AddNode);
cx.action(FlowCanvasCommand::SetLineStyle(1.0));
// Action handling
for action in actions {
if let FlowCanvasAction::StatusUpdate { nodes, edges } = action.cast() {
// Handle update
}
}- Simple drop-in widget via Makepad's
live_design!macro - Clean command pattern for programmatic control
- Action-based event handling follows Makepad conventions
- No builder API: Nodes constructed via internal structs
- No controlled mode: State fully internal to widget
- Limited customization: Colors, sizes hardcoded in shaders
- No trait abstractions: Can't swap node/edge renderers
| Missing Item | Impact |
|---|---|
| README.md | No quickstart, installation, or API reference |
| Crate-level docs | lib.rs has only module exports |
| Inline examples | Only external example binaries |
| API guides | Only gap analysis docs exist |
| Tutorial | No getting started guide |
| Category | xyflow Features | makepad-flow Features | Coverage |
|---|---|---|---|
| Core | 10 | 10 | 100% |
| Node Features | 15 | 5 | 33% |
| Edge Features | 10 | 5 | 50% |
| Interaction | 11 | 5 | 45% |
| Events/Callbacks | 14 | 0 | 0% |
| UI Components | 6 | 0 | 0% |
| Viewport | 8 | 2 | 25% |
| Utilities | 8 | 1 | 12% |
| State Management | 7 | 1 | 14% |
| Persistence | 4 | 1 | 25% |
| Styling | 5 | 1 | 20% |
| TOTAL | 98 | 31 | ~32% |
The dora-viewer example attempts to visualize Dora dataflow YAML files. The voice-chat.yml contains 15 nodes with complex port configurations:
| Node Type | Example | Inputs Required | Outputs Required |
|---|---|---|---|
| MaaS Client | student1 | 2 | 3 |
| Segmenter | multi-text-segmenter | 6 | 6 |
| Controller | conference-controller | 6 | 7 |
| MoFA Widget | mofa-system-log | 27 | 0 |
| Gap | Priority | Status |
|---|---|---|
| Multiple ports per node | BLOCKING | Current: 1 input + 1 output only |
| YAML dataflow parser | BLOCKING | Must parse 450-line YAML |
| Port labels | HIGH | Can't identify connections |
| Auto-layout | HIGH | 15 nodes need arrangement |
| Dynamic node sizing | MEDIUM | Height depends on port count |
| Edge routing | MEDIUM | 27 inputs to one node |
Verdict: Not ready for Dora dataflow visualization without significant development.
-
Add comprehensive README.md
- Quickstart guide
- Installation instructions
- API reference
- Example usage
-
Implement multi-port nodes
- Replace single ports with
Vec<Port> - Port positioning (vertical stack)
- Port-to-port edge connections
- Replace single ports with
-
Add event callback system
onNodesChangecallbackonConnectcallbackonSelectionChangecallback
-
Create utility module
getIncomers()- upstream nodesgetOutgoers()- downstream nodesgetConnectedEdges()- edges for nodes
- MiniMap widget for large graph navigation
- Controls panel with zoom in/out/fit buttons
- Background grid with snap-to-grid option
- Export/import JSON for persistence
- Node resizing with drag handles
- Edge reconnection (drag to new target)
- Connection validation callback
- Auto-layout using dagre or similar
- Theming system (light/dark mode)
- Parent-child node grouping
- Z-index control for layering
- Copy/paste functionality
makepad-flow is a solid foundation with clean code, custom shaders, and good core interactions. The SDF-based rendering and event-driven architecture demonstrate thoughtful design. However, the project is not production-ready for most real-world use cases.
- Missing multi-port support (critical for dataflows)
- No event/callback system (can't integrate with app logic)
- Missing persistence (can't save/load graphs)
- Limited navigation aids (no MiniMap for large graphs)
- Zero documentation (no README, no API docs)
- Simple single-input/single-output node graphs
- Prototyping and experimentation
- Learning Makepad widget development
- Educational purposes
- Production dataflow visualization
- Complex node editors with many ports
- Applications requiring state persistence
- External integration scenarios
- Large graph visualization (>20 nodes)
The project has clear direction (well-documented gaps in ROADMAP.md, API_GAPS.md, DATAFLOW_GAPS.md) but needs significant development to reach feature parity with mature flow libraries like React Flow. The ~30% feature parity indicates substantial work remains.
Recommendation: Use for prototyping and learning only. Do not use in production without addressing critical gaps, especially multi-port nodes and event callbacks.
| File | Lines | Purpose |
|---|---|---|
crates/makepad-flow/src/lib.rs |
14 | Library entry point |
crates/makepad-flow/src/flow_canvas.rs |
2,434 | Core widget implementation |
examples/flow-editor/src/app.rs |
151 | Basic editor example |
examples/dora-viewer/src/app.rs |
306 | Dataflow visualizer |
ROADMAP.md |
74 | Feature plan |
API_GAPS.md |
210 | React Flow comparison |
DATAFLOW_GAPS.md |
254 | Dataflow requirements analysis |
examples/dataflow/voice-chat.yml |
450 | Sample dataflow |
| Component | File | Lines |
|---|---|---|
FlowCanvas widget |
flow_canvas.rs |
~2,000 |
DrawRoundedRect shader |
flow_canvas.rs |
26 |
DrawRoundedTopRect shader |
flow_canvas.rs |
27 |
DrawRoundedBottomRect shader |
flow_canvas.rs |
27 |
FlowNode struct |
flow_canvas.rs |
~100 |
EdgeConnection struct |
flow_canvas.rs |
~50 |
| Undo/redo history | flow_canvas.rs |
~150 |
| Event handling | flow_canvas.rs |
~300 |