I agree to Juian, that using Node-RED as a controller would be more common I think.
Regarding node.js it is single threaded by design, but you have possibiliy to use "fork" instances. So you just create new procecess and it is up to the scheduler how to handle this with your SMP system.
To make interprocess communication more convenient, nodejs provides the cluster module. But nevertheless it means a new V8 engine per new process .. on the other hand everything is isolated, can be distributed etc. this is why nodejs is supposed to be "scaling well".
But this needs to be designed into the architecture of your application ... and in Node-RED it not...
For example: One flow could be a childprocess and the link-node could be IPC-capable. This would give us the benefits that you could the spread the work of a flow over different processes or even machines. An errornous flow would not lead to a total downtime of the runtime but only for the affected flow. By errornous this are not unhandled exceptions, this could be aunresponsive process due to an infinite loop or an outpassing event queue as well. From a point of system architecture you seem to get very much: scalability, robustness, transparency and control.
Downside would be a higher requirement on ressources and additional latency accross flow to flow message passing.
Though this not multithreading as new processes do not share the same memory/adressspace etc.
But as you can be build wrappers for native code for node.js you can incorporate native threads into nodejs. But they need to be synchronized to the nodejs main thread.
So it will be something like ... "calculate this stuff here on the GPU, give me the result etc." You are decoupling tasks from the event loop of nodejs with the possibilty of synchronization. and this is nothing else as "control" an other task.
It follows the Webworker API and use message passing for synchronization with nodejs mainthread.
What I do not really understand from these concepts is how to be performant with a high volume data stream.
For example if it would be possible to share a nodejs Buffer (DoubleBuffer) with native code as a uin8 array where the thread can access to, but it would only be synchronized by message (e.g. by just providing the info: new data in buffer 1)
I do not know if this possible, but that may make it more performant between both worlds. I would need to drive deeper into this...
br
Seb