# Require libraries in a custom node

**URL:** <https://discourse.nodered.org/t/require-libraries-in-a-custom-node/14146>\
**Category:** General\
**Created:** [8 August 2019 15:02 UTC](https://discourse.nodered.org/t/require-libraries-in-a-custom-node/14146 "2019-08-08T15:02:56Z")\
**Posts on this page:** 14\
**Page:** 1

<div class="post-metadata">

**Author:** ![malfarasplux](https://avatars.discourse-cdn.com/v4/letter/m/b77776/32.png) [@malfarasplux](https://discourse.nodered.org/u/malfarasplux)\
**Post date:** [8 August 2019 15:02 UTC](https://discourse.nodered.org/t/require-libraries-in-a-custom-node/14146/1 "2019-08-08T15:02:56Z")

</div>

Hello there,  
I'm trying to set up a bunch of custom nodes that combine p5 library and Mathjs.  
Inspired by the nice contrib-example-lower-case [https://nodered.org/docs/creating-nodes/first-node](https://nodered.org/docs/creating-nodes/first-node) I create the building blocks of my node (html, json and js).  
I then install with the npm install --verbose D:\mydevfolder from the console pointing to the folder where I keep my new node.

In order to import p5 and mathjs I placed them into the same local folder and used **'require' statements** in the javascript.  
Similar to what other contrib-libraries' nodes do:

> <https://github.com/njh/node-red-contrib-osc/blob/master/osc.js>

  

> <https://github.com/stevenaeola/node-red-contrib-music/blob/master/beat.js>

Here is my .js code:

```auto
module.exports = function (RED) {
    'use strict';
	const mathjs = require('./mathjs/dist/math');
	const p5 = require('./p5');
	
	
    function p5SynthNode(config) {
        RED.nodes.createNode(this,config);
        var node = this;
		//my nice functions go here
        node.on('input', function(msg) {			
        node.send(msg);
        });
    }
    RED.nodes.registerType("p5synth",p5SynthNode);
}

```

This is the html:

```auto
<script type="text/javascript">
    RED.nodes.registerType('p5synth',{
        category: 'input',
        color: '#AAAA66',
        defaults: {
            name: {value:""}
        },
        inputs:1,
        outputs:1,
        icon: "feed.png",
        label: function() {
            return this.name||"p5Synth";
        }
    });
</script>

<script type="text/x-red" data-template-name="p5synth">
    <div class="form-row">
        <label for="node-input-name"><i class="icon-tag"></i> Name</label>
        <input type="text" id="node-input-name" placeholder="Name">
    </div>
</script>

<script type="text/x-red" data-help-name="p5synth">
    <p>A simple node that runs a synth p5</p>
</script>

```

The problem is that the node does not appear in the palette.  
Commenting out the p5 require line solves the problem (local mathjs is correctly imported).  
What is the correct way to require libraries when setting up a custom node?

Any help will be appreciated.  
Cheers,

---

<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:** [8 August 2019 15:50 UTC](https://discourse.nodered.org/t/require-libraries-in-a-custom-node/14146/2 "2019-08-08T15:50:11Z")

</div>

The proper way is to include a package.json file in your node that makes it a proper module. In that file you can declare what npm modules your node depends on so that when you run the `npm install` command, npm will take care of installing those dependencies in the right place.

Then, in your code, you don't use relative paths in your `require` statements - you use `require('p5')` and `require('mathjs/dist/math')`.

---

<div class="post-metadata">

**Author:** ![malfarasplux](https://avatars.discourse-cdn.com/v4/letter/m/b77776/32.png) [@malfarasplux](https://discourse.nodered.org/u/malfarasplux)\
**Post date:** [8 August 2019 16:33 UTC](https://discourse.nodered.org/t/require-libraries-in-a-custom-node/14146/4 "2019-08-08T16:33:43Z")

</div>

Thank you very much knolleary.  
I figured out that p5 was raising issues due to window reference (usually available when running as usual via an html). I have it commented out, since I need to circumvent this.

The dependency workflow logic you explain makes sense. I do have a package.json. I did not include any dependencies though.  
I'm now trying it for mathjs, with the following text:

```auto
{
  "name": "p5synth",
  "version": "1.0.0",
  "description": "example syn p5",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "mplux",
  "license": "ISC",
  "node-red" : {
        "nodes": {
            "p5ynth": "p5synth.js"
        }
   },
	"dependencies": {
    "mathjs": "^3.20.2"
  }
}

```

Unfortunately, when the package is reinstalled and Node-RED relaunched, it doesn't pick up the path.

```auto
const mathjs = require('mathjs/dist/math');

```

Perhaps it is not intended at local development. I'm not sure, but I'll have to dig deeper.  
myExample =\>

> **[node-red-contrib-example-synp5.zip](https://drive.google.com/file/d/1ivwS3jU_HUBzvYDUJ3UmSiuVYUYNc_vW/view?usp=sharing)**
>
> Google Drive file.

  
Many thanks.

---

<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:** [8 August 2019 20:11 UTC](https://discourse.nodered.org/t/require-libraries-in-a-custom-node/14146/5 "2019-08-08T20:11:55Z")

</div>

> [@malfarasplux](#):
>
> In order to import p5 and mathjs I placed them into the same local folder and used **'require' statements** in the javascript.

This is not the correct process for consuming Node.js libraries.

You should install them using npm:

```auto
npm install mathjs

```

Then, as Nick says, you can simply do

```auto
const mathjs = require('mathjs')

// or, to use a single function

const { sqrt } = require('mathjs')
console.log(sqrt(-4).toString()) // 2i

```

These things are shown in the [documentation](https://mathjs.org/docs/getting_started.html) and this isn't really a Node-RED issue.

* * *

P5, on the otherhand is a JavaScript version of the Processing language. It is front-end code as it expects and needs a browser as an output medium. I very much doubt it will work in Node.js server environments.

To use it with Node-RED, you need to build a web-page and include the library that way. Node-RED has several methods to do this ranging from the http-in/-out nodes, Dashboard with the Dashboard Template node, or contributed nodes such as my own `uibuilder` (which would make an excellent platform for working with P5 and Node-RED).

---

<div class="post-metadata">

**Author:** ![afelix](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/afelix/32/9743_2.png) [@afelix](https://discourse.nodered.org/u/afelix)\
**Post date:** [8 August 2019 21:27 UTC](https://discourse.nodered.org/t/require-libraries-in-a-custom-node/14146/6 "2019-08-08T21:27:18Z")

</div>

> [@TotallyInformation](#):
>
> This is not the correct process for consuming Node.js libraries.
> 
> You should install them using npm:
> 
> ```auto
> npm install mathjs
> 
> ```

And, to have them immediately end up in that `package.json` file, use

```auto
npm install --save mathjs

```

That will add mathjs to the dependencies. If instead it is needed as dependency during development only, use `npm install --save-dev mathjs` instead

---

<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:** [8 August 2019 21:34 UTC](https://discourse.nodered.org/t/require-libraries-in-a-custom-node/14146/7 "2019-08-08T21:34:41Z")

</div>

> [@afelix](#):
>
> And, to have them immediately end up in that `package.json` file, use
> 
> ```auto
> npm install --save mathjs
> 
> ```

Since npm 5.x, the default behaviour is to update the package.json file (if it exists) with or without the flag.

---

<div class="post-metadata">

**Author:** ![malfarasplux](https://avatars.discourse-cdn.com/v4/letter/m/b77776/32.png) [@malfarasplux](https://discourse.nodered.org/u/malfarasplux)\
**Post date:** [9 August 2019 10:37 UTC](https://discourse.nodered.org/t/require-libraries-in-a-custom-node/14146/8 "2019-08-09T10:37:01Z")

</div>

Thank you. I don't consume Node.js libraries that way. I'm sorry that is what it looked like.  
I was just trying to circumvent the require statement problem mentioned with relative paths, as the global require does not manage to find the libraries.  
The npm install changing the package.json is the way to go.

As per p5, my idea of using it came after noticing its npm [https://www.npmjs.com/package/p5](https://www.npmjs.com/package/p5)  
However, I'll need to tests approaches like the http-out and uibuilder you mention.  
Thanks

---

<div class="post-metadata">

**Author:** ![malfarasplux](https://avatars.discourse-cdn.com/v4/letter/m/b77776/32.png) [@malfarasplux](https://discourse.nodered.org/u/malfarasplux)\
**Post date:** [9 August 2019 10:39 UTC](https://discourse.nodered.org/t/require-libraries-in-a-custom-node/14146/9 "2019-08-09T10:39:15Z")

</div>

Many thanks to everyone.

So, as indicated by knolleary, package.json is updated also when no flag is given.  
I managed to install (within my custom node folder) and use mathjs, no local path 👍  
It modified the package.json and created a local folder with the lib contents.

I'm still puzzled to see that when installing node-red packages like [https://www.npmjs.com/package/node-red-contrib-music](https://www.npmjs.com/package/node-red-contrib-music)  
no node\_modules folder as the one I recently got through npm appears.  
The [https://github.com/stevenaeola/node-red-contrib-music/blob/master/beat.js](https://github.com/stevenaeola/node-red-contrib-music/blob/master/beat.js) I referenced is part of it. I'm trying to understand its behavior. An I think this makes this topic a Node-RED topic.

As regards p5, I'll have to try the suggested approaches.  
Thanks

---

<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:** [9 August 2019 13:07 UTC](https://discourse.nodered.org/t/require-libraries-in-a-custom-node/14146/10 "2019-08-09T13:07:04Z")

</div>

> [@malfarasplux](#):
>
> I'm still puzzled to see that when installing node-red packages like [node-red-contrib-music - npm](https://www.npmjs.com/package/node-red-contrib-music)  
> no node\_modules folder as the one I recently got through npm appears.  
> The [node-red-contrib-music/beat.js at main · stevenaeola/node-red-contrib-music · GitHub](https://github.com/stevenaeola/node-red-contrib-music/blob/master/beat.js) I referenced is part of it. I'm trying to understand its behavior. An I think this makes this topic a Node-RED topic.

This is really an npm topic 😉 however, it doubtless confuses many people.

You need to understand a little more about how npm works. For more recent versions of npm, it attempts to keep the packages as "flat" as possible. What used to happen is that each package got its own `node_modules` folder with its dependencies installed. However, as this can add 10's to 100's of thousands of files, it quickly gets unmanagebly large. So now, it tries to keep everything to a single `node_modules` folder except where there are clashing version requirements.

Here are a couple of links that help you understand:

> **[resolve](https://www.npmjs.com/package/resolve)**
>
> resolve like require.resolve() on behalf of files asynchronously and synchronously. Latest version: 1.22.8, last published: 3 months ago. Start using resolve in your project by running \`npm i resolve\`. There are 8902 other projects in the npm...

> **[Requiring modules in Node.js: Everything you need to know](https://www.freecodecamp.org/news/requiring-modules-in-node-js-everything-you-need-to-know-e7fbd119be8/)**
>
> \> Update: This article is now part of my book “Node.js Beyond The Basics”. Read the updated version of this content and more about Node at jscomplete.com/node-beyond-basics \[https://jscomplete.com/g/node-modules\]. Node uses two core modules for...

And from one of my own helper libraries. Here I have a need to manually find where a package is installed (if it is). If have to jump through hoops because this code is, itself buried in a module that is buried several layers deep in Node-RED. So the standard resolve method in the link above doesn't always work. The JSDoc for that function gives a little more explanation.

[https://github.com/TotallyInformation/node-red-contrib-uibuilder/blob/95a3e817f098a35b9b634d7fc4fe1e017139d9cc/nodes\tilib.js#L133-L133](https://github.com/TotallyInformation/node-red-contrib-uibuilder/blob/95a3e817f098a35b9b634d7fc4fe1e017139d9cc/nodes%5Ctilib.js#L133-L133)

---

<div class="post-metadata">

**Author:** ![Steve-Mcl](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/steve-mcl/32/4826_2.png) [@Steve-Mcl](https://discourse.nodered.org/u/Steve-Mcl)\
**Post date:** [10 August 2019 00:06 UTC](https://discourse.nodered.org/t/require-libraries-in-a-custom-node/14146/11 "2019-08-10T00:06:31Z")

</div>

> [@TotallyInformation](#):
>
> JSDoc for that function gives a little more explanation.
> 
> [https://github.com/TotallyInformation/node-red-contrib-uibuilder/blob/95a3e817f098a35b9b634d7fc4fe1e017139d9cc/nodes\tilib.js#L133-L133](https://github.com/TotallyInformation/node-red-contrib-uibuilder/blob/95a3e817f098a35b9b634d7fc4fe1e017139d9cc/nodes%5Ctilib.js#L133-L133)

Was curious to see this (may have borrowed it) but I get a 404 for that link.

---

<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:** [10 August 2019 00:53 UTC](https://discourse.nodered.org/t/require-libraries-in-a-custom-node/14146/12 "2019-08-10T00:53:55Z")

</div>

Oops, copied from VSCode but it seems to have given me an invalid link.

Here is the correct link (hopefully), sorry about that.

> <https://github.com/TotallyInformation/node-red-contrib-uibuilder/blob/master/nodes/tilib.js#L123-L181>

---

<div class="post-metadata">

**Author:** ![jadster](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/jadster/32/40585_2.png) [@jadster](https://discourse.nodered.org/u/jadster)\
**Post date:** [17 October 2022 14:40 UTC](https://discourse.nodered.org/t/require-libraries-in-a-custom-node/14146/13 "2022-10-17T14:40:14Z")

</div>

How does the functionGlobalContext declaration in settings.js fit into all of this?

---

<div class="post-metadata">

**Author:** ![Steve-Mcl](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/steve-mcl/32/4826_2.png) [@Steve-Mcl](https://discourse.nodered.org/u/Steve-Mcl)\
**Post date:** [17 October 2022 15:02 UTC](https://discourse.nodered.org/t/require-libraries-in-a-custom-node/14146/14 "2022-10-17T15:02:54Z")

</div>

This thread is over 3y old and many things have changed.

If you have a particular question, please start a new thread.

---

<div class="post-metadata">

**Author:** ![Steve-Mcl](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/steve-mcl/32/4826_2.png) [@Steve-Mcl](https://discourse.nodered.org/u/Steve-Mcl)\
**Post date:** [17 October 2022 15:02 UTC](https://discourse.nodered.org/t/require-libraries-in-a-custom-node/14146/15 "2022-10-17T15:02:57Z")

</div>


