Node.JS require(es-module) for Node-RED v5?

Hi, apologies if this has already been covered and I missed it.

I would be absolutely amazing in the v5 release of Node-RED could be linked to node.js v26 as a baseline.

Why? Because require(esm) has now landed as live in v25.4.0 which means that it will be live in the next ESR release, v26. require(esm) should allow greater flexibility for node creators to start using ESM in earnest for developing nodes I believe.

Not had a chance to test this myself yet, I don't currently have an available test environment where I can run node.js v25 and node.js v5.

Anyway, :crossed_fingers:and hoping for node.js v26. It is due to be released in April so not sure if this fits in with the v5 release schedule.

I'm hoping NR5 will be stable long before April - don't really want to delay it unnecessarily.

Node 24 is the targeted default version.

OK, fair enough - here's hoping for a rapid delivery of node-red v6 then. :smiley:

It is getting increasingly hard to find node.js tools that aren't going ESM-only which certainly complicates some integrations with Node-RED.

I've not yet found a realistic way to write nodes as ES Modules without a build step which certainly not only adds build complexity but also debugging complexity.

Perhaps others more knowledgeable that me will find a way.

hasn't ESM been implemented experimentally and backported into current Node.JS?

Oops, I missed that! You are right, though you need v22.12.0+. Confusing that node.js claimed it for v25 without a reminder about v22/v24.

In either case, only ESM's without top-level await's are allowed.

Last time I tried, can't really remember when that was, you couldn't write a node runtime as an ESM - clearly, I need to try again.

I've already moved most Editor code in uibuilder to modules.

OK, so I have created a new node in my testbed. I've verified that the node is correctly registered and appears in the palette if it is a CommonJS runtime module.

If I change it to a an ES Module, it says that it has correctly registered but it does not appear in the palette.

I would be grateful for any ideas on how to progress on this. Feels like we are close but something is missing.

We have this pending PR that claims to add support for ESM models. It's been on the backlog for some time, but had some recent activity and we'll look at adding it for NR5 (maybe backport to NR4 stream at a push).

Maybe kick the tyres of that to see if it helps?

1 Like

OK, try manually replacing the code in the PR into my dev instance.

There is an error in the code in that let importPromise = import(node.file); does not reliably work because imports have to be URL's, not file paths. Kind-of works probably on Linux but certainly not on Windows.

I'll leave a comment on the PR for the fix.

However, sadly, this does not fix the issue of the module not appearing in the editor.

So I would say that, as long as you assume that NR v5 will use the LTS version of node.js v24, the PR is unnecessary since require loads MOST ESM's anyway - just so long as they don't have a top-level await.

Any clues as to where I could find some NR code where the nodes are added to the palette? I could maybe trace the issue there.

Tried again, this time with the lower-case node example to keep things as simple as possible.

Played with a number of combinations and I've found one that works.

While Node-RED is happy loading a module something.cjs or something.mjs, when loading something.mjs - the module is not added to the palette.

But if you rename to something.js - it works.

So there is a small bug in the core code somewhere. In fact, didn't we come across this a while back - I vaguely remember reporting an issue - ah yes, loader.js cannot handle *.cjs files Ā· Issue #5220 Ā· node-red/node-red Ā· GitHub

The fix for that issue only implemented *.cjs file handling. I would suggest that, at least for v5, *.mjs file handling should also be accommodated.


I've done some quick tests having manually updated the previous fix with additions for *.mjs and it works as expected.

I've only tested with node.js v24 though. v22.12+ should also work as expected. I don't think node-red's v4 baseline of v18 will work?

My framework and plugin allows devs to author nodes using ESM, including importing es modules. Then it builds to commonjs.

Im about to release core and vite as standalone packages, and update nrg to use this new template.

Doing ESM based node runtimes with a build step is easy enough - though the issue there is that error reporting can end up pointing to things that are not human comprehensible without running under node.js with source maps enabled.

Once Node-RED v5 is released, we can move the baseline node.js version up and then, as I've shown, as long as you avoid using top-level async, you will be able to write node runtimes as ESM's natively with no build step.

Using ESM for the Editor code has always worked as long as you use a browser that supports ESM's. Really not a problem as all browsers have supported them for ages now.

There are already many node.js libraries and packages that only support ESM so this is a really important change for Node-RED since otherwise, it would be in real danger of becoming obsolete.

esbuild + rollup