# Using p5.js via npm

**URL:** https://discourse.processing.org/t/using-p5-js-via-npm/35914
**Category:** Beginners
**Created:** [March 24, 2022, 7:07am UTC](https://discourse.processing.org/t/using-p5-js-via-npm/35914 "2022-03-24T07:07:15Z")
**Posts on this page:** 10
**Page:** 1

<div class="post-metadata">

### Author: ![JaPatProccesingDis](https://avatars.discourse-cdn.com/v4/letter/j/dc4da7/32.png) [@JaPatProccesingDis](https://discourse.processing.org/u/JaPatProccesingDis)
#### Post date: [March 24, 2022, 7:07am UTC](https://discourse.processing.org/t/using-p5-js-via-npm/35914/1 "2022-03-24T07:07:15Z")

</div>

Hey there!  
I downloaded p5 via npm locally in one of my projects. Now how do I import it to the `index.html` file?

Is doing this worth it? Or should I rather abandon this idea and use the CDN instead?

---

<div class="post-metadata">

### Author: ![GoToLoop](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/gotoloop/32/86_2.png) [@GoToLoop](https://discourse.processing.org/u/GoToLoop)
#### Post date: [March 24, 2022, 7:40am UTC](https://discourse.processing.org/t/using-p5-js-via-npm/35914/2 "2022-03-24T07:40:40Z")

</div>

- Let’s say you have a folder named “MySketch”.
- And inside that folder a file called “sketch.js”:

```javascript
'use strict';

function setup() {
  createCanvas(800, 600).mousePressed(redraw);
  noLoop();
}

function draw() {
  background('#' + hex(~~random(0x1000), 3));
}

```

- Then you open the command shell while inside that folder and type in: npm i -D p5
- You’ll get a subfolder “node\_modules” and 2 files: “package.json” & “package-lock.json”.
- In order to load both “sketch.js” and the acquired “p5.js” file inside “node\_modules/p5/lib/” you’d create an “index.html” template like this:

```auto
<script defer src=node_modules/p5/lib/p5.js></script>
<script defer src=sketch.js></script>

```

- However you could simply scrap all that and just get it remotely from a CDN:

```auto
<script defer src=https://cdn.JsDelivr.net/npm/p5></script>
<script defer src=sketch.js></script>

```

---

<div class="post-metadata">

### Author: ![JaPatProccesingDis](https://avatars.discourse-cdn.com/v4/letter/j/dc4da7/32.png) [@JaPatProccesingDis](https://discourse.processing.org/u/JaPatProccesingDis)
#### Post date: [March 30, 2022, 3:28pm UTC](https://discourse.processing.org/t/using-p5-js-via-npm/35914/3 "2022-03-30T15:28:32Z")

</div>

Thank you @GoToLoop.  
I have another question: I have my project inside a long path of sub-folders. So is there a way I can lead the `path` variable staright to the root repository and then into the node modules?

---

<div class="post-metadata">

### Author: ![GoToLoop](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/gotoloop/32/86_2.png) [@GoToLoop](https://discourse.processing.org/u/GoToLoop)
#### Post date: [March 30, 2022, 3:47pm UTC](https://discourse.processing.org/t/using-p5-js-via-npm/35914/4 "2022-03-30T15:47:28Z")

</div>

You can use `../` in order to go up to the parent folder of the current folder.

You can also begin from the base folder by starting the path w/ `/`:

```auto
<script defer src=/node_modules/p5/lib/p5.js></script>

```

---

<div class="post-metadata">

### Author: ![dxd3ab1de5](https://avatars.discourse-cdn.com/v4/letter/d/f14d63/32.png) [@dxd3ab1de5](https://discourse.processing.org/u/dxd3ab1de5)
#### Post date: [March 31, 2023, 8:32am UTC](https://discourse.processing.org/t/using-p5-js-via-npm/35914/5 "2023-03-31T08:32:23Z")

</div>

@GoToLoop thanks for sharing info how to use p5.js with npm.

i have managed to use it via import p5 from ‘p5’ in main.js  
and import main.js in index.html

`<script type="module" src="./main.js" />`

```auto
// inside main.js
import p5 from "p5";

/* method 1 */
function sketch1() {
  setup = () => {
    createCanvas(400, 400);
  }

  draw = () => {
    background(220);
    stroke(0);
    fill(255);
    ellipse(200, 200, 100, 100);
  }
}

new p5(sketch1);

/* method 2 */
const sketch2 = (p5) => {
  p5.setup = () => {
    p5.createCanvas(400, 400);

  };

  p5.draw = () => {
    p5.background(220);
    p5.stroke(0);
    p5.fill(255);
    p5.ellipse(200, 200, 100, 100);
  };
}

new p5(sketch2);

```

in JSDoc for p5 I read:

> This is the p5 instance constructor. A p5 instance holds all the properties and methods related to a p5 sketch. It expects an incoming sketch closure and it can also take an optional node parameter for attaching the generated p5 canvas to a node. The sketch closure takes the newly created p5 instance as its sole argument and may optionally set preload(), setup(), and/or draw() properties on it for running a sketch.  
> A p5 sketch can run in “global” or “instance” mode: “global” - all properties and methods are attached to the window “instance” - all properties and methods are bound to this p5 object

My question: how do i change modes ?

ideally it would be great to use sketch only declaring setup and draw functions and calling them with p5, instead inside of a sketch function. Is it possible? It seems minor thing but I find it much cleaner than method 1, and since global context is already used perhaps this could work too somehow?

```auto
function setup() {
    createCanvas(400, 400);
 }

 function draw () {
    background(220);
    stroke(0);
    fill(255);
    ellipse(200, 200, 100, 100);
 }

new p5({ setup, draw });

```

---

<div class="post-metadata">

### Author: ![GoToLoop](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/gotoloop/32/86_2.png) [@GoToLoop](https://discourse.processing.org/u/GoToLoop)
#### Post date: [April 1, 2023, 3:12am UTC](https://discourse.processing.org/t/using-p5-js-via-npm/35914/6 "2023-04-01T03:12:50Z")

</div>

> [@dxd3ab1de5](#):
>
> I have managed to use it via `import p5 from 'p5'` in “main.js”.

AFAIK, library p5.js isn’t available as an [ES6 module](https://en.wikibooks.org/wiki/JavaScript/Modules#ECMAScript_modules_(ES_modules)):

So we can’t use keyword [`import`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import) for it; it needs to be downloaded as a regular JS file from within an HTML file.

> [@dxd3ab1de5](#):
>
> `new p5({ setup, draw });`

Constructor p5’s 1st parameter is a callback function, not a regular object.

When constructor p5 calls back our function, it passes the newly created instance.

If you wanna use instance mode, but prefer to have callbacks such as **setup()** & **draw()** as top-functions rather than inside a single callback, you can follow this model:

> <https://github.com/GoSubRoutine/Steering-Text-Paths/blob/v1.1.6/dist/sketch.mjs#L19-L26>

---

<div class="post-metadata">

### Author: ![dxd3ab1de5](https://avatars.discourse-cdn.com/v4/letter/d/f14d63/32.png) [@dxd3ab1de5](https://discourse.processing.org/u/dxd3ab1de5)
#### Post date: [April 1, 2023, 8:15am UTC](https://discourse.processing.org/t/using-p5-js-via-npm/35914/7 "2023-04-01T08:15:01Z")

</div>

ES6 imports work with no problem once you import your script in index.html with `type="module" `attribute.

The only thing weird is that P5 methods are available only via global scoped variables (you define own `setup` and `draw` as variables inside the sketch function that is passed to P5 constructor.

Thanks to this trick you don’t need to call `p5.createCanvas` etc but simply `createCanvas`.

This way though is exploiting what would normally be a javascript anti-pattern (setup and draw are being hoisted implicitly and ‘caught’ by p5 context, making p5 methods available). I think it would be good to mention this in the docs as it is not standard use of JS and modules.

---

<div class="post-metadata">

### Author: ![GoToLoop](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/gotoloop/32/86_2.png) [@GoToLoop](https://discourse.processing.org/u/GoToLoop)
#### Post date: [April 1, 2023, 8:20am UTC](https://discourse.processing.org/t/using-p5-js-via-npm/35914/8 "2023-04-01T08:20:12Z")

</div>

> [@dxd3ab1de5](#):
>
> ES6 imports work with no problem once you import your script in index.html with type=“module” attribute.

Library p5.js isn’t officially available as a ES6 module, so we can’t use keyword `import` to acquire it.

We can only use `import` for actual ES6 module files, like “vehicle.mjs” in the example below:

> <https://github.com/GoSubRoutine/Steering-Text-Paths/blob/v1.1.6/dist/sketch.mjs#L16-L17>

---

<div class="post-metadata">

### Author: ![dxd3ab1de5](https://avatars.discourse-cdn.com/v4/letter/d/f14d63/32.png) [@dxd3ab1de5](https://discourse.processing.org/u/dxd3ab1de5)
#### Post date: [April 1, 2023, 8:23am UTC](https://discourse.processing.org/t/using-p5-js-via-npm/35914/9 "2023-04-01T08:23:23Z")

</div>

Any plans to make it available officially for ES6 modules? it is pretty standard these days.

---

<div class="post-metadata">

### Author: ![GoToLoop](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/gotoloop/32/86_2.png) [@GoToLoop](https://discourse.processing.org/u/GoToLoop)
#### Post date: [April 1, 2023, 8:29am UTC](https://discourse.processing.org/t/using-p5-js-via-npm/35914/10 "2023-04-01T08:29:58Z")

</div>

Library p5.js got modularized using CommonJS syntax, even though ES6 module syntax was already available back then:

> **[CommonJS](https://en.wikipedia.org/wiki/CommonJS)**
>
> CommonJS is a project with the goal to establish conventions on the module ecosystem for JavaScript outside of the web browser. The primary reason for its creation was a major lack of commonly accepted forms of JavaScript module units which could be reusable in environments different from that provided by conventional web browsers running JavaScript scripts (e.g. web servers or native desktop applications).
> CommonJS's module specification is widely used today, in particular for server-side JavaS...

> <https://github.com/processing/p5.js/blob/main/src/app.js>
