Standalone visual comparison of flows - in browser

Hi There!

I've created a little tool for comparing flows visually, for example

To create your own visualisations, go to Comparing Flows and paste your two flows into the textboxes.

You can create link with the flows BUT most urls become too long and the server complains - your mileage will vary (the above link is under that limit).

The tool has various colours for nodes: black/grey means a node was removed, green it was added, yellowish/green means it was moved and purple means it was changed - clicking on the nodes sometimes brings up a diff popup with the changes (depending on the what happened to the node). Use the slider to transition between the two versions of the flow. If it's a large flow.json file, the the selector will be filled with the various flow tabs. As seen over here.

Various bugs exist but it's up to the user to find them! :slight_smile: Please provide feedback and suggestions, this is just a proof of concept implementation!

The tool is completely running in the browser, no server involved. Permissions is given to steal, copy and modify BUT don't do any evil. Attribution is also always a kind gesture.



Great stuff - love seeing your progress.

Now you have this in a re-usable form outside of node-red, it would be great if it were an NPM module that others could import. Bonus points for a CDN.

And I havent forgotten about seeing if I can populate the node catalog with icon and colour info (just havent got around to it)


PS: apart from visualising the node, text and position, is the diff supposed to highlight things like changed IDs or props?


Thanks Steve, it's been fun work using Node-RED for doing this.

Can you point me in the direction of an example NPM package that does what you describe? I'm don't have many NPM experiences and I certainly don't know the best practices when it comes to creating packages.

That's just GitHub - GitHub - gorenje/ image content for - that was my GitHub flow, i.e. the reason I built it - so that I could get a cdn for free! :wink:

IDs would become additions/deletions, props are compared and become changed node i.e. purple in colour. I use the same comparison code that Node-RED uses with some extensions though.

Edit: Apropo prop change, this example is one -- click on the purple node "Git commit - Press Here" and you'll see a prop change.

(ignore the don't press here notice)

Prop comparison is done because of this else it was always [object Object].

Edit2: for those interested in the codebase, it's once again a Node-RED flow.

1 Like

WARNING: Probably a lot of stuff you already know so my apologies for teaching you to suck eggs.

So, forgetting ESM or Deno for a moment, using your viewer in a run of the mill project would typically be imported via npm e.g. const gregsViewer = required('name-of-your-package') so publishing to NPM is a great way to get this out there.

Similarly, using this actually in node-red, a user can import (require) your module by entering it in the setup tab of a function node. This would enable a user to import this & use it on (for example) a dashboard, uibuilder, pdfMake, a straight endpoint, or wherever!

Something like

// const const gregsViewer = required('name-of-your-package') // imported via setup tab
msg.payload = gregsViewer.flowToSVG(msg.payload)
return msg; // return the SVG generated by gregsViewer

The tricky part - naming.

As it is not a Node-RED node package or plugin (YET :wink: ) naming can really be whatever you wish however you might want to scope it to your NPM username. e.g. @gornje/flow2svg or @gornje/nr-flow-utils or anything really.

The easy part - packaging.

To publish your module to NPM, you will need to package up the node.

  1. Create a new directory e.g. flow2svg
  2. cd to the directory
  3. initialise it as a package - enter npm init & answer the questions...
$ npm init
This utility will walk you through creating a package.json file.
It only covers the most common items, and tries to guess sensible defaults.

See `npm help init` for definitive documentation on these fields
and exactly what they do.

Use `npm install <pkg>` afterwards to install a package and
save it as a dependency in the package.json file.

Press ^C at any time to quit.
package name: (flow2svg) @gorenje/flow2svg
version: (1.0.0) 0.0.1-beta.1
description: A stand-alone utility package for visualising Node-RED flows
entry point: (index.js) flowviewer.js
test command:
git repository:
keywords: node-red,flow,viewer
author: gorenje
license: (ISC) Apache-2.0
About to write to \flow2svg\package.json:

  "name": "@gorenje/flow2svg",
  "version": "0.0.1-beta.1",
  "description": "A stand-alone utility package for visualising Node-RED flows",
  "main": "flowviewer.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  "keywords": [
  "author": "gorenje",
  "license": "Apache-2.0"

Is this OK? (yes)
  1. open the directory it in your fav editor (vscode?), drop the necessary files in
  2. update the package.json file - add other fields e.g.
    • "repository": { "type": "git", "url": "" }
    • "bugs": { "url": "" }
    • "engines": { "node": ">=14.x" } 
    • "files": [ "", "LICENSE", "file1.js", "file2.html" ]
  3. Publish as alpha/beta
    • npm publish --tag beta
  4. try it in a node-red function node / ask others to try it out
  5. titivate
  6. bump version number to something better (e.g. 1.0.0) and publish it for real
    • npm publish --tag beta

TIP: Do not include copies of JQuery or any other external packages in your package - this leads to duplication, larger packages, collisions and other nasty issues. Instead, you would include them as dependencies or peer dependencies in your package.json

Version Numbers. Node and NPM generally use sematic versioning. Early releases are often 0.0.1 or 0.1.0 or even 1.0.0-alpha.1 - you decide, but users expect the patch/minor/major version number changes to reflect compatibility or incompatibility.

Happy to help you out if you wish - I'm around for the next hour or 2.

1 Like


I would work now but gotta do some afk work... I'll have a tomorrow :+1:

Ah, I would also set this up to be a github action of some sort, ie the code would be developed in node red, push to github into a repo and then a github action to push off to npmjs.

Commiting to github via node Red is really simple and I can avoid terminal work. Plus all the development is done remote, no local hard drive needed.

I had a look at doing this since I won't mind having something outside of the browser for other purposes however I began to realise that this is harder than it might appear.

The reason for this is the fact that the plugin "draws" the SVG in the browser and then depends on that rendering to compute things such as group sizes (i.e. the size of the group box to surround all members of the group). It does this by using getBBox() (in fact that gets used quite often) which can only work if the the SVG is already rendered in the browser (or some other headless creature).

So I had a quick look and found JSDOM which does quite a lot but which doesn't implement the getBBox() on SVG elements (or any other elements).

Hence I'm leaving this for an extremely rainy day (which in my part of the world do occur) and am moving on to other things.