# Inheritance of custom nodes

**URL:** <https://discourse.nodered.org/t/inheritance-of-custom-nodes/47282>\
**Category:** Developing Nodes\
**Created:** [17 June 2021 08:23 UTC](https://discourse.nodered.org/t/inheritance-of-custom-nodes/47282 "2021-06-17T08:23:10Z")\
**Posts on this page:** 16\
**Page:** 1

<div class="post-metadata">

**Author:** ![H3llsing](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/h3llsing/32/40624_2.png) [@H3llsing](https://discourse.nodered.org/u/H3llsing)\
**Post date:** [17 June 2021 08:23 UTC](https://discourse.nodered.org/t/inheritance-of-custom-nodes/47282/1 "2021-06-17T08:23:10Z")

</div>

Hey there,

im writing currently a lot of custom nodes for my company and im interested in a general concept of custom node inheritance.  
Im dividing my functionality from the ui part. that allows me to use another node as dependency and using its library functions in my new node.  
But apparently i also want to use some core node functionalities. Like the Schema-Validation of the json node and i do not want to reimplement always functionality into my new node!

Does it make sense to you to setup a best practice guideline for reusage of nodes or do you think its better to completly divide the nodes to avoid clashes if one node updates it's functionality and breaks a node which is using it as dependency?

---

<div class="post-metadata">

**Author:** ![dceejay](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/dceejay/32/38_2.png) [@dceejay](https://discourse.nodered.org/u/dceejay)\
**Post date:** [17 June 2021 08:43 UTC](https://discourse.nodered.org/t/inheritance-of-custom-nodes/47282/2 "2021-06-17T08:43:13Z")

</div>

As with all things with dependencies it will depend on your attitude to risk. There will always be a risk that some dependency may change and break things. Indeed the schema-validation has just changed in the core json node to drop some old versions that you may have needed...  
So if you plan to actively maintain your nodes on an ongoing basis then you can monitor and keep up with dependency changes then you may be ok. If you plan to just release your nodes and only fix them when broken then they may be more stable if you rely on fewer dependencies... up to you.

---

<div class="post-metadata">

**Author:** ![H3llsing](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/h3llsing/32/40624_2.png) [@H3llsing](https://discourse.nodered.org/u/H3llsing)\
**Post date:** [17 June 2021 09:07 UTC](https://discourse.nodered.org/t/inheritance-of-custom-nodes/47282/3 "2021-06-17T09:07:52Z")

</div>

Hey dceejay,

thanks for the reply. I think for me and my nodes it makes sense because i will maintain them actively.  
But my question was more focused on the core nodes. Currently there is no option to make an inheritance of a node right? Because the .js file is to closely coupled with the node red node functions like

```auto
this.on("input", function(msg,send,done) {
...

```

or am i missing something here how to extend the functionality of an existing node?  
Lets say i would like to use the validation function of the json core node in my custom node.

> <https://github.com/node-red/node-red/blob/ajv-update/packages/node_modules/@node-red/nodes/core/parsers/70-JSON.js>

is it possible to include the complete module and use the node.on... functions ?

---

<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:** [17 June 2021 09:20 UTC](https://discourse.nodered.org/t/inheritance-of-custom-nodes/47282/4 "2021-06-17T09:20:24Z")

</div>

No, we do not have any established pattern for node inheritance.

---

<div class="post-metadata">

**Author:** ![H3llsing](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/h3llsing/32/40624_2.png) [@H3llsing](https://discourse.nodered.org/u/H3llsing)\
**Post date:** [17 June 2021 09:34 UTC](https://discourse.nodered.org/t/inheritance-of-custom-nodes/47282/5 "2021-06-17T09:34:28Z")

</div>

Would it make sense to you to do it in the future?

Here is the way im currently doing it.  
Im used to build a lib.js for my nodes.  
Example:

```auto
const commonLib = require('../common-lib')

class Thing {

    validateSomething(object){
       // function code
    }

    onCreate(RED, node, config) {                   
    }

    onInput(RED, node, msg, send, done) {
        this.validateSomething(msg.something)
        done()
    }

    onClose(RED, node, done) {
        done()
    }

}

module.exports = { Thing }

```

in my actual node.js im including this lib.js like

```auto
module.exports = function (RED) {
    "use strict";
    const lib = require('./lib')

    function ThingNode(config) {
        RED.nodes.createNode(this, config);
        const node = this;
        if (config.once === undefined) { config.once = true; }
        if (config.showOnlyTabId === undefined) { config.showOnlyTabId = true; }

        node.showOnlyTabId = config.showOnlyTabId
        node.once = config.once;
        node.onceDelay = (config.onceDelay || 0.1) * 1000;

        let thing = new lib.Thing()

        // creates
        thing.onCreate(RED, node, config)

        node.on('input', function (msg, send, done) {
            thing.onInput(RED, node, msg, send, done)
        });
             
        node.on('close', function (done) {
            thing.onClose(RED, node, done)
        });
    }

    RED.nodes.registerType("thing", ThingNode);
}

```

then im able to use this node as a dependency in another node and use it's lib functionality  
like the validateSomething(object)

---

<div class="post-metadata">

**Author:** ![BartButenaers](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/bartbutenaers/32/10476_2.png) [@BartButenaers](https://discourse.nodered.org/u/BartButenaers)\
**Post date:** [17 June 2021 10:37 UTC](https://discourse.nodered.org/t/inheritance-of-custom-nodes/47282/6 "2021-06-17T10:37:31Z")

</div>

Hi @H3llsing,  
I have recently put some of the shared logic of two of my nodes into npm package [nr-msg-statistics](https://www.npmjs.com/package/nr-msg-statistics?activeTab=dependencies). It is added as a dependency e.g. in my [node-red-contrib-msg-speed](https://www.npmjs.com/package/node-red-contrib-msg-speed) as a dependency, where I create a subclass.  
Perhaps not the best way to do it, but it now saves me a lot of work...  
Bart

---

<div class="post-metadata">

**Author:** ![H3llsing](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/h3llsing/32/40624_2.png) [@H3llsing](https://discourse.nodered.org/u/H3llsing)\
**Post date:** [17 June 2021 11:11 UTC](https://discourse.nodered.org/t/inheritance-of-custom-nodes/47282/7 "2021-06-17T11:11:25Z")

</div>

hey @BartButenaers,  
thanks for sharing. Looks like the same concept. Outsourcing functionality and including it in other nodes.  
With one difference, you made an extra npm package out of it which is great if someone wants to use your functionality without node-red.

I think it would be great if we could make a guideline for this =\> Inheritance of nodes and how to create them.

---

<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:** [17 June 2021 19:42 UTC](https://discourse.nodered.org/t/inheritance-of-custom-nodes/47282/8 "2021-06-17T19:42:04Z")

</div>

I think this comes down as well to the usual development dilemma. Whether to split something into its own module/library or not. In uibuilder, I have a couple of modules. One contains generic utilities that I might want to reuse called `tilib.js` and indeed I have reused that in another of my nodes, but only a manual copy. At some point I might well convert that single .js module into a package though so that it can be easily reused.

For the core nodes, there might well be code that could benefit by being split into a separate module file which could then be used in multiple places and in other contrib nodes - but how does anyone know? And, as always, who is on hand to do the work?

I would imagine that, with a bit of confirming discussion, Nick might be more than happy if someone were prepared to learn enough about the core code to split something into a separate module file 😀 Particularly if that someone also reworked some tests and perhaps even suggested some improvements or bug fixes!

Of course, some documentation would also be needed, especially if that module were to be used by contrib nodes.

Just an idea. But hopefully you can see that it would take a bit of effort and that has to be balanced against all of the other priorities.

---

<div class="post-metadata">

**Author:** ![BartButenaers](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/bartbutenaers/32/10476_2.png) [@BartButenaers](https://discourse.nodered.org/u/BartButenaers)\
**Post date:** [17 June 2021 21:17 UTC](https://discourse.nodered.org/t/inheritance-of-custom-nodes/47282/9 "2021-06-17T21:17:45Z")

</div>

> [@H3llsing](#):
>
> With one difference, you made an extra npm package

@H3llsing,  
How do you share your lib.js file between your nodes, which are located in separate npm modules? Is a copy of your lib.js file somehow included in every npm module of every of your nodes?

---

<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:** [17 June 2021 22:04 UTC](https://discourse.nodered.org/t/inheritance-of-custom-nodes/47282/10 "2021-06-17T22:04:33Z")

</div>

Just put it and publish it in its own package Bart, then make it a dependency of your node packages.

---

<div class="post-metadata">

**Author:** ![BartButenaers](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/bartbutenaers/32/10476_2.png) [@BartButenaers](https://discourse.nodered.org/u/BartButenaers)\
**Post date:** [18 June 2021 05:05 UTC](https://discourse.nodered.org/t/inheritance-of-custom-nodes/47282/11 "2021-06-18T05:05:19Z")

</div>

Hi Julian,  
That is indeed how I have done it. But @H3llsing seems to share his lib.js between his nodes, without using a separate npm package for lib.js (if I understood him correctly). So I was wondering how he has achieved that...

---

<div class="post-metadata">

**Author:** ![dceejay](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/dceejay/32/38_2.png) [@dceejay](https://discourse.nodered.org/u/dceejay)\
**Post date:** [18 June 2021 06:01 UTC](https://discourse.nodered.org/t/inheritance-of-custom-nodes/47282/12 "2021-06-18T06:01:55Z")

</div>

If you bundle all your related nodes in one package, then you can place the shared routines in a file in the package of nodes and require it using a relative path.

---

<div class="post-metadata">

**Author:** ![H3llsing](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/h3llsing/32/40624_2.png) [@H3llsing](https://discourse.nodered.org/u/H3llsing)\
**Post date:** [18 June 2021 08:03 UTC](https://discourse.nodered.org/t/inheritance-of-custom-nodes/47282/13 "2021-06-18T08:03:17Z")

</div>

in the parent node which is using the dependency node you can do something like this:

```auto
const paramCheck = require('mynode-contrib-param-check/lib')
paramCheck.doCheck(msg, paramsToCheck)

```

in the parent node package file:

```auto
  "dependencies": {
    "mynode-contrib-param-check": "1.0.6",

```

so they do not need to be bundles into one package 🙂  
i think thats because they will install these dependencies into a sub node-modules folder.

`.node-red/node_modules/your-package/node_modules`

---

<div class="post-metadata">

**Author:** ![H3llsing](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/h3llsing/32/40624_2.png) [@H3llsing](https://discourse.nodered.org/u/H3llsing)\
**Post date:** [18 June 2021 08:13 UTC](https://discourse.nodered.org/t/inheritance-of-custom-nodes/47282/14 "2021-06-18T08:13:40Z")

</div>

yes of course 2.0 has prio and maybe with this step and the growing knowledge of Typescript the core nodes could be refactored.  
i've took a deep look over the last month into some core nodes but as all of us i got just a little bit of freetime and there are other construction sites that need to be finished 🙂

I would like to rework some nodes,but apparently my company do not have a concept for working on open source yet. So i only my afterwork time can be used for this but it's in discussion.

---

<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:** [18 June 2021 08:18 UTC](https://discourse.nodered.org/t/inheritance-of-custom-nodes/47282/15 "2021-06-18T08:18:33Z")

</div>

You can even create data that is shared between **_instances_** of your nodes as I've now done in uibuilder with all of the ExpressJS code. I moved it to a separate module as a class. The class operates as a "singleton" which means that it is instantiated in the module and therefore (thanks to the mechanics of `require`) only once no matter how many times you `require` it. See `web.js` in uibuilder. I did the same for all of the [Socket.IO](http://Socket.IO) processing (`socket.js`).

Because all code in Node-RED runs in the same Node.js instance, that also means that other nodes could reference the ExpressJS and [Socket.io](http://Socket.io) class instance created by uibuilder.

---

<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:** [17 August 2021 08:18 UTC](https://discourse.nodered.org/t/inheritance-of-custom-nodes/47282/16 "2021-08-17T08:18:38Z")

</div>

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