Using of SemVer

Hi,

this is a sort of issue for custom nodes creators, related to node-red not following SemVer.

TL;DR @node-red developers, please use SemVer

The long explanation

I found that node-red does not use SemVer for tracking its version.
Why I say this? Because the new release 3.0.x is a new major, which means that custom nodes see it as a breaking change.
But actually the API for the nodes are the same... so a custom node must be re-released just to make the version 3.0.x supported in the package.json.
And yes, we should declare the supported node-red versions in our custom nodes, probably as peer-dependency, as good practice mandates.

The proposal

So the final point is: node-red versioning just reflects the development of the tool itself, but not the actual internal API versioning, and this is bad for custom nodes maintenance.

Two solutions are possible:

  1. Switch node-red to SemVer, to reflect the API status
  2. Or split the node-red API (and its type definitions) in a separate package, which will follow SemVer, and make the custom nodes track such a package (so node-red versioning will be able to evolve as it please).
    • In this case, also the node-red-node-test-helper module will track such a new API module. In any case, it will have to follow SemVer too for its versioning

So I here suggest to the node-red team to please adopt one of the proposed solutions (or if you have better ideas, it is fine for me as long as my nodes are not broken due to a new node-red release).

Meanwhile, I will re-release my custom nodes, by removing node-red version constraints, as a bad temporary workaround.

Regards

We absolutely do follow SemVer.

We dropped support for Node 12. That is a major change to the API support. If your nodes required Node 12, they would have been broken on Node-RED 3.0.

Just to add to this, the version constraint is more typically used to identify the minimum version of Node-RED your nodes support.

As a general policy, we don't make breaking changes to the APIs that nodes use. With around 4000 nodes in the community, to publish a change that required them all to be updated would be reckless and completely self-defeating.

1 Like

Hi,

thank you for the reply and the clarification.

So basically, since changing node.js version is not usually an issue (especially for simple software as many custom nodes, or for projects using typescript as mines), what solution are you suggesting? Maybe using a >= instead of ^ to specify the node-red dependency?

Regards

I'm suggesting you use it to specify the minimum version of Node-RED your nodes support. In other words, use >=

Hi,

I see. My concern is that if in the future node-red will do a breaking change in the API, my nodes will not recognize this till testing or usage... That's why as a general rule. the ^ specifier should be preferred.

So I still believe imho that the current situation is problematic.
Maybe it is possible to track node.js dependency by using something like this in the package.json:

  "engines" : { 
    "npm" : ">=7.0.0",
    "node" : ">=16.0.0"
  }

And to not use node-red version to track these changes.
This should do the trick (to be tested -- I have just found the field).
Do you think this could be possible?

Regards

Just to way in here.

?

"node-red": {
	"version": "^2.0.0 || ^3.0.0"
}

Do you mean within Node-RED itself, or in your own node?

Dropping support for major versions of Node.js is a semver major change. There is no way around that. If we published a minor version update which dropped support for a version of node, it would instantly break those users. That is not acceptable.

Hi,

I mean, using that in node-red and custom nodes.
The idea is: since node.js version is tracked in both, custom nodes should refuse to install.
I am thinking to something like the following example:

  • In node-red: "node" : ">=16.0.0"
  • In the custom node 1: "node": "^14.0.0"
  • In the custom node 2: "node": ">=14.0.0" or "node": "^14.0.0 || ^16.0.0" or whatever is correct for this node

I am expecting such a custom node 1 should fail to install, which is what we want, since it does not support node 16. Viceversa, custom node 2 should still work.
And this would require just a node-red minor, stating that the API are compatible, so that custom node 2 should work just fine without any change (and without forcing its re-publishing).

Regards

Node-RED already does have an engines entry:

Hi,

nice, so if the proposed strategy works, it would be enough to just not do a major of node-red in the future.

Regards.

I still do not follow your reasoning here.

If we drop support for an old version of node, and change engines to, for example >=18 - then that is a semver major change because it will break users still running Node 14.

I don't know how else to say the same thing.

Hi,

I am simply telling that if you avoid to increase node-red major in case of dropping an engine version, custom nodes should still work as expected, thanks to the engines entry, which means:

  • installing and working if compatible
  • not installing if not compatible

In other words, imho there is no need to reflect in a major that you have dropped an engine, since it is already clearly stated (and managed as expected) by the engines field. So it is enough to create a minor, and everything should work fine.

For example, the "custom node 2" in my previous post would work fine.

Or to say in other words again, imho changing the engines is not (or should not be) a major but a minor.

Why I think so? Because users will not be broken by surprise at runtime: if they will try to install a newer node-red on a not supported node version, node-red will not install at all (thanks to the engines field).

As stated, I have not tested this... but it is easy to check.
And I am not an expert of SemVer, so maybe you should truly do a major, but to me it seems more practical and useful to do a minor.

Regards.

Dropping support for a version of node.js is very widely considered to be a semver major change. This isn't just us being difficult. I can point to many examples in the node.js community which supports this position.

For production environments, updating the version of Node.js is not a minor activity. If we did a sem-ver minor change that meant those users could no longer upgrade, they would no longer be able to receive security fixes and the like. That is not an acceptable position for a production-grade application.

By making it a semver major change, we are able to put the previous version into maintenance. We still ship maintenance releases against 2.x for the next year. That allows users who cannot update their node.js version on our schedule to still receive security fixes and upgrade on their schedule.

2 Likes