# How can i make a singleton node

**URL:** <https://discourse.nodered.org/t/how-can-i-make-a-singleton-node/96009>\
**Category:** Developing Nodes\
**Created:** [14 March 2025 17:00 UTC](https://discourse.nodered.org/t/how-can-i-make-a-singleton-node/96009 "2025-03-14T17:00:43Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![papenfort](https://avatars.discourse-cdn.com/v4/letter/p/73ab20/32.png) [@papenfort](https://discourse.nodered.org/u/papenfort)\
**Post date:** [14 March 2025 17:00 UTC](https://discourse.nodered.org/t/how-can-i-make-a-singleton-node/96009/1 "2025-03-14T17:00:43Z")

</div>

Just imagine for a second you were trying to create a singleton-node for managing some http-context-specific "global state", why cant you throw an error in a constructing function to prevent the node vom initializing?

just take this code as an example(ts):

```typescript
const nodeInit: NodeInitializer = (RED): void => {
    function BaseNodeNodeConstructor(
      this: Node,
      config: NodeDef
    ): void {
      //just for testing
      throw new Error("i hope i cant create this node");
    }
    RED.nodes.registerType("test-node", BaseNodeNodeConstructor);
  };
  
  export = nodeInit;

```

i defined the custom node to throw an error as a test, the error shows up in the console:  
 ![grafik](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/4/6/469fae2e215e1c0f16eda9affda86b352c09df52.png)

and for some reason the node _ **still** _ registers in the flow-editor...

is there any other way enforcing a node being a singleton?

---

<div class="post-metadata">

**Author:** ![TotallyInformation](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/totallyinformation/32/31_2.png) [@TotallyInformation](https://discourse.nodered.org/u/TotallyInformation)\
**Post date:** [14 March 2025 17:12 UTC](https://discourse.nodered.org/t/how-can-i-make-a-singleton-node/96009/2 "2025-03-14T17:12:50Z")

</div>

> [@papenfort](#):
>
> why cant you throw an error in a constructing function to prevent the node vom initializing?

Porobably because Node-RED tries very hard not to crash?

> [@papenfort](#):
>
> is there any other way enforcing a node being a singleton?

I think so, though I've not actually tried. It isn't, of course, the "normal" operating mode.

You could try to put a trap in the Editor to prevent users from creating another node. In UIBUILDER for example, I have some code that monitors the node add/change/remove events:

 ![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/b/9/b98e0a8eba66d498deb9360891f4446b58f1ac99.png)

You could use something similar to prevent creation of a new instance of a node. I use it to make sure that no two uibuilder nodes have the same url.

---

<div class="post-metadata">

**Author:** ![knolleary](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/knolleary/32/3_2.png) [@knolleary](https://discourse.nodered.org/u/knolleary)\
**Post date:** [14 March 2025 17:14 UTC](https://discourse.nodered.org/t/how-can-i-make-a-singleton-node/96009/3 "2025-03-14T17:14:50Z")

</div>

The editor doesn't provide a way to enforce this type of constraint - it isn't a use case we've had to address before (at least, not commonly enough for anyone to have contributed anything in this area).

The general approach would be add a listener (in the editor) to the `nodes:add` and `nodes:remove` event to keep track of how many nodes of this particular type have been added. (as @TotallyInformation has suggested whilst I type this)

But the editor doesn't provide a way to block adding a second node to the workspace based on any custom validation or rules. At best, you could then use `RED.notify("Uh oh")` to warn the user they have made a grave mistake.

There are a bunch of edge cases you'd need to think about. Dragging a node into the workspace isn't the only way a node can be added. There's copy/paste and import to consider. They all trigger the same set of `node:add` events ultimately.

---

<div class="post-metadata">

**Author:** ![papenfort](https://avatars.discourse-cdn.com/v4/letter/p/73ab20/32.png) [@papenfort](https://discourse.nodered.org/u/papenfort)\
**Post date:** [14 March 2025 17:30 UTC](https://discourse.nodered.org/t/how-can-i-make-a-singleton-node/96009/4 "2025-03-14T17:30:28Z")

</div>

okay, i get how i would "enforce" a singleton, im very thankful of that.  
I just wonder wether having a node that isnt even initialized, because

```auto
RED.nodes.createNode(this, config);

```

hasnt been called yet, showing up in the editor could be considered a bug or a feature.  
I guess sometimes things just do be like that.

---

<div class="post-metadata">

**Author:** ![knolleary](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/knolleary/32/3_2.png) [@knolleary](https://discourse.nodered.org/u/knolleary)\
**Post date:** [14 March 2025 17:53 UTC](https://discourse.nodered.org/t/how-can-i-make-a-singleton-node/96009/5 "2025-03-14T17:53:34Z")

</div>

It isn't a bug. The editor shows you what the flow configuration contains. If it contains two nodes of a particular type, it shows you those nodes.

If it hid any nodes that encountered an error whilst starting, then you'd have no way to edit/fix the node.

---

<div class="post-metadata">

**Author:** ![papenfort](https://avatars.discourse-cdn.com/v4/letter/p/73ab20/32.png) [@papenfort](https://discourse.nodered.org/u/papenfort)\
**Post date:** [14 March 2025 18:04 UTC](https://discourse.nodered.org/t/how-can-i-make-a-singleton-node/96009/6 "2025-03-14T18:04:04Z")

</div>

i would have expected it it to error out when i hit deploy, tho, perhaps i overestimated what the editor is supposed to do and what not.  
thanks for the heads up, im rather new to node-red, so im sure this information will prove to be very helpful in the future!

---

<div class="post-metadata">

**Author:** ![TotallyInformation](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/totallyinformation/32/31_2.png) [@TotallyInformation](https://discourse.nodered.org/u/TotallyInformation)\
**Post date:** [14 March 2025 19:32 UTC](https://discourse.nodered.org/t/how-can-i-make-a-singleton-node/96009/7 "2025-03-14T19:32:29Z")

</div>

> [@papenfort](#):
>
> i would have expected it it to error out when i hit deploy, tho, perhaps i overestimated what the editor is supposed to do and what not.

But surely, generally you would not want a poorly coded node to prevent Node-RED from starting? And indeed, how would the palette manager cope in such a case? The nature of Node-RED is that you want it to be as stable as possible. So a poorly coded or misconfigured node should indeed raise an error in the log but should only cause NR to stop in very extreme cases. Then I can still remove the node using the palette manager and Node-RED continues to work.

---

<div class="post-metadata">

**Author:** ![omrid](https://avatars.discourse-cdn.com/v4/letter/o/77aa72/32.png) [@omrid](https://discourse.nodered.org/u/omrid)\
**Post date:** [15 March 2025 09:59 UTC](https://discourse.nodered.org/t/how-can-i-make-a-singleton-node/96009/8 "2025-03-15T09:59:23Z")

</div>

Maybe I'm missing something or stating the obvious - why can't you define the singleton profile as a related configuration node, this way regardless of how many nodes the user adds, the profile exists only once, and its state can be reflected in a global context var?

---

<div class="post-metadata">

**Author:** ![papenfort](https://avatars.discourse-cdn.com/v4/letter/p/73ab20/32.png) [@papenfort](https://discourse.nodered.org/u/papenfort)\
**Post date:** [15 March 2025 10:18 UTC](https://discourse.nodered.org/t/how-can-i-make-a-singleton-node/96009/9 "2025-03-15T10:18:32Z")

</div>

to be honest, i dint know that was a thing. I only started using node-red yesterday, while having done a fair share of work with nodejs/webdev/typescript in general. i basicially came in with the wrong assumption that the experience can translate 1 to 1 to node red, which obviously proved to be wrong.  
I was basicially just confused with the error-handling of the runtime.  
dont get me wrong, stability should be the utmost priority in node red, i get that, but in my opinion its just not very intutive for exceptions in the startup of a node to not register in the editor at all. i would have at least expected the node to have a visual marker that says something like "hey, i have an uncought error and **cant** work", instead of basicially halting the flow that relies on the node in question, which is very annoying in my opinion. But these are just my two cents.

---

<div class="post-metadata">

**Author:** ![Mike7833](https://avatars.discourse-cdn.com/v4/letter/m/58956e/32.png) [@Mike7833](https://discourse.nodered.org/u/Mike7833)\
**Post date:** [10 April 2025 16:07 UTC](https://discourse.nodered.org/t/how-can-i-make-a-singleton-node/96009/10 "2025-04-10T16:07:37Z")

</div>

You could keep state across all your nodes with a class using static:

```auto
'use strict';
const NODE_TYPE = "<YourNodeType>";

class NodeRedNode {

    static messageReceivedCount = 0;

    constructor(RED, thisNode, config) {
        thisNode.config = config;

        thisNode.on('input', function(msg, send, done) { 

            console.log(NodeRedNode.messageReceivedCount++);
            
            send(msg); // Send the message onwards (if applicable)
            done(); // Call done when finished

        });

        thisNode.on('close', function(done) {
            done();
        });

    }

}

module.exports = function(RED) {
    RED.nodes.registerType(NODE_TYPE, function(config) {
        RED.nodes.createNode(this, config);
        this._instance = new NodeRedNode(RED, this, config);
    });
};

```

But I may be mis-understanding what you want...

---

<div class="post-metadata">

**Author:** ![system](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/1X/d073cd938eafa2e558d7c2cd59003b3ef4963033.png) [@system](https://discourse.nodered.org/u/system)\
**Post date:** [9 June 2025 16:07 UTC](https://discourse.nodered.org/t/how-can-i-make-a-singleton-node/96009/11 "2025-06-09T16:07:39Z")

</div>

This topic was automatically closed 60 days after the last reply. New replies are no longer allowed.
