Interactive NATS messaging diagrams built with React Flow. This project can be used both as a standalone development environment and as a library bundle for static sites.
npm install
npm run devThis starts the Vite dev server with hot reload for developing components.
npm run build:libCreates production bundles in dist/:
natsflow.js- Standalone bundle with React and all dependenciesnatsflow.css- Component styles
Use case: You have a static site without React and want to embed interactive NATS diagrams.
Entry point: src/lib.tsx (self-contained bundle)
npm run build:libnpm run build:copy # Copies to ../static/Or manually copy:
dist/natsflow.js→ your static assets folderdist/natsflow.css→ your static assets folder
Make sure you hard refresh in the browser to see the changes. The browser could cache those JS/CSS files so on refresh you may not see them. You can confirm they copied over by making a small change, building, copying, and looking at the static/js/ or static/css folder in the Hugo project.
Add to your page's frontmatter:
---
title: "My Page"
hasNatsFlow: true
---The NatsFlow CSS and JS will automatically load only on pages with hasNatsFlow: true.
In your Markdown or HTML:
<div
class="nats-flow"
data-scenario="publishSubscribe"
data-width="800"
data-height="400"
data-show-controls="true">
</div>How it works:
lib.tsxbundles React, ReactDOM, and all NatsFlow components into one file- When loaded, it automatically scans for
.nats-flowelements and renders them - Includes a MutationObserver to handle dynamically added content
Use case: You have a React-based site where React is already loaded by the framework.
Entry point: src/loader.ts (expects external React)
- Import NatsFlow components and loader in your app:
import { NatsFlow } from './components/NatsFlow';
import { scenarios } from './components/NatsFlow/scenarios';
import './loader';
// Expose to window for loader
window.React = React;
window.ReactDOM = ReactDOM;
window.NatsFlow = { NatsFlow, scenarios };
// Notify loader
window.dispatchEvent(new Event('natsflow-loaded'));- Use
.nats-flowdivs in your content as shown above.
How it works:
loader.tswaits for React/ReactDOM to be available onwindow- Waits for your NatsFlow components to be loaded
- Initializes diagrams after all dependencies are ready
- More efficient than
lib.tsxsince it doesn't duplicate React
| Feature | lib.tsx |
loader.ts |
|---|---|---|
| Use case | Static sites (Hugo, Jekyll) | React apps (Docusaurus) |
| React bundled? | ✅ Yes, includes React | ❌ No, expects external React |
| File size | Larger (~150KB+) | Smaller (~10KB) |
| Dependencies | Self-contained | Requires React on window |
| Best for | Non-React sites | React-based sites |
publishSubscribe- Basic pub/sub pattern with NATS server
Configure diagrams using data attributes:
data-scenario(required) - Name of the scenario to renderdata-width(optional, default: 600) - Width in pixelsdata-height(optional, default: 400) - Height in pixelsdata-show-controls(optional, default: false) - Show React Flow controls
src/
├── components/
│ ├── ExampleFlow/ # Example interactive flow
│ └── NatsFlow/ # Main NatsFlow component
│ ├── scenarios/ # Scenario definitions
│ ├── nodes/ # Custom node types
│ └── edges/ # Custom edge types
├── lib.tsx # Library entry (for static sites)
├── loader.ts # Loader (for React apps)
├── main.tsx # Dev app entry
└── App.tsx # Dev app component
- Create a new file in
src/components/NatsFlow/scenarios/:
import type { NatsFlowScenario } from '../../../types';
export const myScenario: NatsFlowScenario = {
description: 'My custom scenario',
nodes: [
// your nodes
],
edges: [
// your edges
],
};- Export it from
src/components/NatsFlow/scenarios/index.ts:
export { myScenario } from './myScenario';- Add to scenarios object:
export const scenarios = {
// ...
myScenario,
};- Rebuild:
npm run build:lib