React Flow MVP for visualising a Skupper VMS Compose-style YAML file.
The app focuses on making bindings consumable rather than drawing every possible relationship at once. It treats the model as:
- Library blocks: reusable
Blockdefinitions. - Instance blocks: runtime instances created from composite bodies.
- Interfaces: visible ports on block cards.
- Bindings: edges between specific interfaces, including
superbindings. - Generated resources: resource chips extracted from simple block templates.
- Validation notes: role mismatch, missing interfaces, implicit polarity, max-binding checks, and TODO-style compatibility notes.
The bundled sample is public/examples/nearestprime.yaml, copied from the uploaded instance. An additional comprehensive example is available in example.yaml - see example.md for detailed documentation of this invoice processing platform use case.
React Flow is used because this UI needs custom cards, handles/ports, grouped nodes, selectable edges, and interactive scope changes. The MVP intentionally avoids a full all-edges-at-once topology view because that becomes unreadable quickly.
- Node.js 20 or newer recommended
- npm
just, optional but recommended
npm install
npm run devOr with just:
just install
just devOpen the Vite URL shown in the terminal.
npm run build
npm run previewThis project includes a GitHub Actions workflow for automatic deployment to GitHub Pages.
Quick setup:
- Enable GitHub Pages in repository settings (Settings → Pages → Source: GitHub Actions)
- Push to
mainbranch - Site will be live at
https://<username>.github.io/compose-flow-mvp/
See DEPLOYMENT.md for detailed instructions.
- Pan: Click and drag on empty canvas space to move around
- Zoom: Use mouse wheel or pinch gesture
- Fit View: Click the fit-view button in controls (bottom-left)
- MiniMap: Use the mini-map (bottom-right) for overview and quick navigation
See INTERACTION_GUIDE.md for detailed interaction documentation.
You can load Compose YAML files in four ways:
- Load Complex Example: Click the "Load Complex Example" button to load the comprehensive invoice platform example (12 blocks, 24 instances, 23 bindings)
- Upload Button: Click the "Upload YAML" button in the top bar to select a file from your computer
- Drag and Drop: Drag a YAML file from your file manager and drop it anywhere on the workspace
- Share URL: Open a share URL someone sent you - it contains the YAML embedded in the URL
The app will automatically parse and visualize your file. The current filename is shown below the title.
Click the Share button to generate a shareable URL:
- The current YAML and all view settings are encoded into the URL (similar to kroki.io)
- URL is automatically copied to your clipboard and updates in your address bar
- Send the URL to anyone - they'll see your exact view (same diagram, layout, spacing, toggles, etc.)
- No server or file hosting needed - works on static GitHub Pages
- Example:
https://example.com/app#<base64-encoded-json> - Encoded settings: view mode, layout, spacing, interface toggles, root, scope
- Tip: After clicking Share once, you can always copy the URL from your address bar
Bundled Examples:
nearestprime.yaml- Simple example (default on load)example.yaml- Complex invoice processing platform (click "Load Complex Example" button)
- Start with View: landscape and Scope: nearestprime/container.
- Switch Scope to
nearestprime/container/mainAppto inspect the app internals. - Switch View to bindings to show interface ports.
- Click an edge to inspect the binding.
- Use resources to see Kubernetes/Skupper generated resource chips.
- Use validation to expose role/polarity/max-binding notes.
- Try different Layout options:
- Auto Grid - Adaptive square grid (default)
- Horizontal - Left-to-right flow
- Vertical - Top-to-bottom flow
- Grid (3 cols) - Fixed 3-column grid
- Adjust Spacing slider (0.5x - 2.0x) to control distance between blocks
The default is deliberately scoped. Enable include descendants only when you need a deeper view.
The CLI accepts file input or stdin, writes JSON to stdout by default, and logs diagnostics to stderr.
node scripts/compose-to-flow.mjs public/examples/nearestprime.yaml > flow.json
cat public/examples/nearestprime.yaml | node scripts/compose-to-flow.mjs - > flow.json
node scripts/compose-to-flow.mjs public/examples/nearestprime.yaml -o flow.jsonUse a specific root block:
node scripts/compose-to-flow.mjs public/examples/nearestprime.yaml --root nearestprime/main > main-flow.jsonnpm run export:sample
npm run test:normalizerThe test compares the normalized graph against tests/golden/nearestprime-flow.json.
.
├── public/examples/nearestprime.yaml # sample Compose YAML
├── src/App.jsx # app shell and controls
├── src/components/BlockNode.jsx # React Flow block/card node
├── src/components/Inspector.jsx # selected block/binding details
├── src/components/LibraryPanel.jsx # library block catalog
├── src/components/ProblemsPanel.jsx # validation notes
├── src/compose/composeModel.js # parser, instantiator, validator
├── src/compose/flowElements.js # graph-to-React-Flow conversion
├── scripts/compose-to-flow.mjs # pipe-friendly CLI normalizer
├── scripts/test-normalizer.mjs # golden test runner
├── tests/golden/nearestprime-flow.json # expected normalized graph
├── docs-source-model.md # copied first/reference doc
├── justfile
└── package.json
- ✅ Error boundary with graceful error handling
- ✅ Loading states for better UX
- ✅ File upload via button or drag-and-drop
- ✅ Code splitting for optimized bundle size
- ✅ Accessibility improvements with ARIA labels
- ✅ Visual drag-and-drop feedback
- Layout algorithms are simple (horizontal, vertical, grid). Add ELK later if large graphs need crossing reduction or advanced auto-layout.
- Polarity is reported as implicit when the YAML omits it. The MVP does not infer the project runtime defaults.
- Block-type compatibility is intentionally reported as an info note because the source model treats it as a TODO.
- Template rendering is not executed. Generated resources are extracted from template text by scanning for
apiVersionandkind. - The app does not currently persist manual node positions.
- File System Access API (upload button) requires modern browsers (Chrome/Edge 86+, Safari 15.2+). Drag-and-drop works everywhere.
- Add an ELK layout button.
- Add a binding table that highlights paths on hover.
- Add collapse/expand controls for composite nodes.
- Render
superbindings with a distinct containment-boundary glyph. - Add a generated YAML preview for a selected instance.
- Add a file-open workflow using the File System Access API.