# Problem using p5 'esm' via jsdeliver (cdn)

**URL:** https://discourse.processing.org/t/problem-using-p5-esm-via-jsdeliver-cdn/46279
**Category:** Beginners
**Created:** [April 25, 2025, 10:04pm UTC](https://discourse.processing.org/t/problem-using-p5-esm-via-jsdeliver-cdn/46279 "2025-04-25T22:04:57Z")
**Posts on this page:** 4
**Page:** 1

<div class="post-metadata">

### Author: ![dalanicolai](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/dalanicolai/32/20617_2.png) [@dalanicolai](https://discourse.processing.org/u/dalanicolai)
#### Post date: [April 25, 2025, 10:04pm UTC](https://discourse.processing.org/t/problem-using-p5-esm-via-jsdeliver-cdn/46279/1 "2025-04-25T22:04:57Z")

</div>

Hello,

I am very new to javascript and even more to ES modules. However, I think I am trying things out correctly here. But as I am not sure if I am doing things right, I first drop a question here before I report an issue at either jsdeliver or p5. My final question will be: is this a bug, or am I doing things wrong?

I am trying to use the p5 via cdn as esm from jsdeliver. However, when trying to load my html, the console reports

```html
jsdelivr-header.js:7 Uncaught SyntaxError: The requested module '/npm/@davepagurek/bezier-path@0.0.2/+esm' does not provide an export named 'createFromCommands' (at jsdelivr-header.js:7:1)

```

as far as I could find in [here](https://github.com/davepagurek/bezier-path/blob/f32f4560bcae7db8b442b6b1d8a6ac15dbd9d4bd/src/conversion.ts#L63) in the bezier-path source, the `createFromCommands` command does get exported (but again I am totally new to modules, so I am not sure if my conclusion is right).

As I am not sure how to use esm modules, I asked ‘Gemini AI’ for a usage example. Trying to use that example results in the same error.  
Here is my html

```auto
<!DOCTYPE html>
<html>
<head>
  <title>p5.js ESM from jsDelivr Example</title>
  <style>
    body { margin: 0; }
    canvas { display: block; }
  </style>
</head>
<body>
  <script type="module">
    import p5 from 'https://cdn.jsdelivr.net/npm/p5@2.0.1/+esm';

    let x = 100;
    let y = 100;
    let speedX = 2.5;
    let speedY = 3;

    function setup() {
      createCanvas(400, 300);
      noStroke();
      fill(255, 0, 150);
    }

    function draw() {
      background(220);
      ellipse(x, y, 50, 50);
      x += speedX;
      y += speedY;

      if (x > width - 25 || x < 25) {
        speedX *= -1;
      }
      if (y > height - 25 || y < 25) {
        speedY *= -1;
      }
    }

    // You can also use the instance-based approach if you prefer
    // const mySketch = function(p) {
    // let circleX = 50;
    // let circleY = 50;
    //
    // p.setup = function() {
    // p.createCanvas(200, 150);
    // p.fill(0, 100, 200);
    // p.noStroke();
    // };
    //
    // p.draw = function() {
    // p.background(240);
    // p.circle(circleX, circleY, 30);
    // circleX += 1;
    // if (circleX > p.width + 15) {
    // circleX = -15;
    // }
    // };
    // };
    //
    // new p5(mySketch);

  </script>
</body>
</html>

```

So now again my question, is the above described behavior due to a bug or me doing things the wrong way?

Thank you!

---

<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 26, 2025, 5:47am UTC](https://discourse.processing.org/t/problem-using-p5-esm-via-jsdeliver-cdn/46279/2 "2025-04-26T05:47:07Z")

</div>

> [@dalanicolai](#):
>
> `<script type="module">`

A JS script using _type_ “module” doesn’t behave the same way as a regular 1.

1 of its many “gotchas” is related to declaring variables using keywords `var` & `function`.

For example, your 2 functions `function setup() {}` & `function draw() {}` will have different global visibility depending on whether they’re being run using _type_ “module” or not!

For regular JS script type, the variable declaring keyword `function` (and `var` as well) will also append the variables _setup_ & _draw_ on the `globalThis`:

> **[globalThis - JavaScript | MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/globalThis)**
>
> The globalThis global property contains the global this value, which is usually akin to the global object.

However, for _type_ “module”, that won’t happen!

B/c neither **setup()** nor **draw()** callbacks are present on `globalThis`, p5js won’t “see” them; and thus your sketch won’t run!

As a workaround, you can manually add those 2 function variables as `globalThis` properties:

```js
globalThis.setup = setup;
globalThis.draw = draw;

```

---

<div class="post-metadata">

### Author: ![dalanicolai](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/dalanicolai/32/20617_2.png) [@dalanicolai](https://discourse.processing.org/u/dalanicolai)
#### Post date: [April 26, 2025, 8:27am UTC](https://discourse.processing.org/t/problem-using-p5-esm-via-jsdeliver-cdn/46279/3 "2025-04-26T08:27:12Z")

</div>

That is very useful information, I would be one step closer to getting the ‘module’ setup to work. Just, I still need to get rid of that error message when trying to use the ‘esm’ library.  
I guess, there is something wrong with that ‘esm’ package on jsdeliver, but I am not sure (how it should work). Anyway, after getting it ‘imported’ I will be aware of your ‘advice’. Thank you very much for this explanation 🙂

---

<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 26, 2025, 8:34am UTC](https://discourse.processing.org/t/problem-using-p5-esm-via-jsdeliver-cdn/46279/4 "2025-04-26T08:34:20Z")

</div>

Officially there’s no ESM version of p5js.  
p5js has always been a regular non-ESM frontend library.

And by the looks of that bezier-path:

> <https://github.com/davepagurek/bezier-path/blob/f32f4560bcae7db8b442b6b1d8a6ac15dbd9d4bd/src/conversion.ts#L1-L3>

Those imports are incompatible w/ browser ESM syntax b/c they’re using filenames w/o their extension!

For example, `import { BezierSegment } from "./BezierSegment";`  
should be instead: `import { BezierSegment } from "./BezierSegment.ts";`

Browsers only accept the full filename, including its extension, for the keyword `import`.
