Making virtual links visible

Following the long discussions around the new linkcall feature in Node-RED 5.0, we said we'd look at how to make the virtual wires visible in the editor.

By virtual wires, I'm referring to the implicit wires that exist between some nodes but aren't otherwise seen in the editor. There are two types of these virtual wires:

  1. The Complete/Catch/Status nodes have a virtual wire to any of the nodes they are targeting; they will get triggered when a corresponding event happens on the connected node
  2. The Link Call node (and, with NR5, the Function node) - which is an inline-node that can make a call to another node and get a response back.

I've spent some time today exploring what we can do. At this stage, I've focussed on the first type; this is because there is an opportunity to reuse a lot of existing code used by the link in/out nodes to draw virtual links when they are selected.

I want to really stress the point that this is a couple hours exploration of the problem. I'm not presenting a full and complete solution. Here's where I've got to:

May-07-2026 16-34-22

  1. Selecting a Catch/Complete/Status node that is connected to specific nodes will show a virtual (dotted) wire to those nodes.
  2. In the case of the Catch node that can be configured to 'catch all' or 'catch in the group' - I found showing all of the resulting wires got very messy. So instead, it shows a pill with a corresponding label. Room for improvement, but a pragmatic compromise in my opinion.

There are some things that aren't working yet.

  1. The virtual links only show when selecting the Complete/Catch/Status node. Selecting a node at the other end doesn't show the returning link.
  2. The whole linkcall situation

My goal so far has been to explore the problem space, dust of areas of the code base I've not touched in some time and see how this can get added in a clean way.

Rather than hardcode knowledge of the Complete/Catch/Status nodes in the editor to do this, those nodes can provide hints to the editor as part of their definition:

Here's the Catch nodes definition. The wires function returns either an array of the nodes its connected to virtually, or a string label to show in the pill button.

    virtualInput: {
            wireable: false,
            wires: function () {
                if (this.scope === null) {
                    return 'all'
                } else if (this.scope === "group") {
                    return 'group'
                } else if (Array.isArray(this.scope)) {
                    return this.scope;
                }
            }
        },

Again, I'm not sure if that's the right API and it may change as we tackle link call connections.

Will share more updates on this thread as my exploration progresses.

For the catch group case, perhaps instead of a pill, use a grey-dotted highlight around the group:

Screen Recording 2026-05-08 at 11.02.25-2

So something like the orange border when a group is selected but in grey to match the iconography of the virtual linking.

That does nothing for me to indicate "This code does something beyond the normal flow routing".

Looking at Nick's mockup, I wonder if these grey wires could be shown as if attached to a virtual connector at the centre right of the node's icon (but running underneath the node), and have the curviness dialled down a bit, more of an arc than an ogive (?).
This would emphasise their special nature.

Not my place to try and design the UI of course!

@jbudd one of the design challenges to solve is how to represent this sort of 'middle of the node' port.

We have other elements around the node body (status text below and change/error badges above) that will interfere with any top/bottom ports.

But this is the space I'm exploring - and why I'm going to share regular updates on the experiments to see what people think.

If the catch for the group is within the group and clearly shows "catch:group", that seems sufficient to me. I wouldn't think that anything "clever" needs to be done for that case?

I see a combo of words and visual good simply because words may be confusing. Also consider the case if the catch node isn’t a member of that group? Ie it’s within the bounds of the group but isn’t a member. Also nested groups can be an issue…

So there are potential edge cases here.

EDIT:

The two edge cases I meant:

Screen Recording 2026-05-08 at 16.58.31

Catch is member of the outer group but visually the inner group.

Screen Recording 2026-05-08 at 17.00.20

Catch is member of neither group

I'm not saying these are likely and neither is good style however I can easily construct these cases.

Having the extra visual effect would negate both straight away.