# How do you make your own (personal) library of scripts?

**URL:** https://forum.babylonjs.com/t/how-do-you-make-your-own-personal-library-of-scripts/43781
**Category:** Questions
**Tags:** npm, library, vite
**Created:** [September 2, 2023, 4:59pm UTC](https://forum.babylonjs.com/t/how-do-you-make-your-own-personal-library-of-scripts/43781 "2023-09-02T16:59:30Z")
**Posts on this page:** 8
**Page:** 1

<div class="post-metadata">

### Author: ![addem](https://avatars.discourse-cdn.com/v4/letter/a/c57346/32.png) [@addem](https://forum.babylonjs.com/u/addem)
#### Post date: [September 2, 2023, 4:59pm UTC](https://forum.babylonjs.com/t/how-do-you-make-your-own-personal-library-of-scripts/43781/1 "2023-09-02T16:59:30Z")

</div>

I have made a few functions to abstract some stuff that I plan on doing over and over in many different projects. Therefore I have my current project in one directory, but also the library of functions in a different directory. For example (the details of what’s in the library aren’t very important for my question, I don’t think, but if anyone wants to see more of the code, I can include it):

In `lib\library.ts`,

```auto
import { ArcRotateCamera, Color3, Engine, HemisphericLight, MeshBuilder, Scene, Vector3 } from "@babylonjs/core";
import { GridMaterial } from "@babylonjs/materials";
import { AdvancedDynamicTexture, Rectangle } from '@babylonjs/gui';

const black = new Color3(0,0,0);

export let init = function(canvasId: string, width="500px", height="500px") {
    const canvas = document.querySelector<HTMLCanvasElement>(canvasId);
    if (canvas == null) {throw new Error("canvas id not found");}

    canvas.style.width = width;
    canvas.style.height = height;

    const engine = new Engine(canvas,true);
    const scene = new Scene(engine);

    scene.useRightHandedSystem = true;

    const camera = new ArcRotateCamera("Camera", 0,0,1, Vector3.Zero(), scene);
    camera.attachControl(canvas, true);
    camera.setPosition( new Vector3(0,-2,20) );
    camera.cameraDirection.set( 0,5,-20 );

    const light = new HemisphericLight("light", new Vector3(.5,1,0), scene);
    light.intensity = .7;
    scene.ambientColor = new Color3(.1,.2,.3);

    return {canvas, engine, scene, camera, light};
}

... (so on with more functions)

```

In `\vite-project\src\proj.ts`

```auto
import './style.css';
import {Engine, Scene, ArcRotateCamera, Vector3, Color3, HemisphericLight, MeshBuilder, AxesViewer, UniversalCamera, DynamicTexture, StandardMaterial} from "@babylonjs/core";
import {GridMaterial} from '@babylonjs/materials';
import {AdvancedDynamicTexture, GUI3DManager, HolographicSlate, Rectangle, TextBlock} from '@babylonjs/gui';

import {init, spinsphere, textbox, twodgrid} from "/Users/ax/BabylonScripts/main";

const p1bag = init("#p1");
const p1scene = p1bag.scene;

twodgrid(p1scene);
spinsphere(p1scene, 0,0);
spinsphere(p1scene, 1,1,0, 0,1,0, .2, true);
spinsphere(p1scene, 2,1,0, 0,0,1);

... (so on with making the rest of the app, making calls to functions written in library.ts)

```

Now I know that all the code works, since I can run the app and it looks how I intend, with no console errors. (By running `yarn dev` in the terminal.)

But when I try to build it, I think understandably, NPM complains.

```auto
/Users/ax/BabylonScripts/main.ts:3:51 - error TS2307: Cannot find module '@babylonjs/gui' or its corresponding type declarations.

3 import { AdvancedDynamicTexture, Rectangle } from '@babylonjs/gui';

```

The problem is that the library script lives outside of any project – which is what I want, because it shouldn’t be attached to any project. But it also calls on BabylonJS packages, which it can’t find, because it’s developed outside of … whatever it is. NPM, Yarn, Vite, whichever of those are responsible for “knowing” about the BabylonJS packages.

I’m guessing that I should “manually” make the library into an NPM package (i.e. in the `\lib` directory run `npm init`), and then in the `package.json` file, include BabylonJS as a dependency. So I did this and edited the file to look like this:

```auto
{
  "name": "babylonscripts",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "dependencies": {
	  "@babylonjs/core": "^6.19.1",
	  "@babylonjs/gui": "^6.19.1"
  },
  "license": "ISC"
}

```

But this didn’t resolve the issue.

One slightly funny thing is that this is only a problem for `@babylonjs/gui`. I’m also using `@babylonjs/core` and `@babylonjs/materials` and neither of these show an error in intellisense or in the build process. Only the GUI library causes an error, both in intellisense and the build.

* * *

I guess also it only now occurs to me that I did all of this in the context of using Yarn and Vite, because I was following a YouTube walk-through. But the instructions in the documentation talk about Webpack. Maybe I should switch? I don’t know much about either of these, I’m mostly just doing what seems to be working for other people.

---

<div class="post-metadata">

### Author: ![jeremy-coleman](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/jeremy-coleman/32/15493_2.png) [@jeremy-coleman](https://forum.babylonjs.com/u/jeremy-coleman)
#### Post date: [September 3, 2023, 1:15pm UTC](https://forum.babylonjs.com/t/how-do-you-make-your-own-personal-library-of-scripts/43781/2 "2023-09-03T13:15:54Z")

</div>

Thats a typescript error. Add skipLibCheck: true to your tsc config, will probably fix it. Wont fix it if you have declarations with lib. Tbh, imo its better to not emit declarations and just put a “types” field in your package json and point it to your source files. That way, you’re never missing any types in a monorepo and your code is the source of truth for types.

---

<div class="post-metadata">

### Author: ![addem](https://avatars.discourse-cdn.com/v4/letter/a/c57346/32.png) [@addem](https://forum.babylonjs.com/u/addem)
#### Post date: [September 3, 2023, 4:46pm UTC](https://forum.babylonjs.com/t/how-do-you-make-your-own-personal-library-of-scripts/43781/3 "2023-09-03T16:46:07Z")

</div>

Am noob.

I don’t have declarations with lib, so I’m interpreting this as saying “You should have declarations, and you should set it up via the types field pointing to source files.” Big if true, I’ll look into what any of this means.

Thanks! 🙂

---

<div class="post-metadata">

### Author: ![jeremy-coleman](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/jeremy-coleman/32/15493_2.png) [@jeremy-coleman](https://forum.babylonjs.com/u/jeremy-coleman)
#### Post date: [September 3, 2023, 5:56pm UTC](https://forum.babylonjs.com/t/how-do-you-make-your-own-personal-library-of-scripts/43781/4 "2023-09-03T17:56:15Z")

</div>

Not suggesting you need to do either. just add skipLibCheck:true to your tsconfig first, it’ll prob fix it. Actually, id say just get comfortable with ts/js etc before you try to manage multiple projects finding each other on your drive. Copy paste works great. No need to make problems for yourself to solve.

---

<div class="post-metadata">

### Author: ![sebavan](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/sebavan/32/57_2.png) [@sebavan](https://forum.babylonjs.com/u/sebavan)
#### Post date: [September 4, 2023, 5:14pm UTC](https://forum.babylonjs.com/t/how-do-you-make-your-own-personal-library-of-scripts/43781/5 "2023-09-04T17:14:51Z")

</div>

Adding @RaananW our lib guru 🙂

---

<div class="post-metadata">

### Author: ![RaananW](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/raananw/32/28955_2.png) [@RaananW](https://forum.babylonjs.com/u/RaananW)
#### Post date: [September 4, 2023, 5:26pm UTC](https://forum.babylonjs.com/t/how-do-you-make-your-own-personal-library-of-scripts/43781/6 "2023-09-04T17:26:45Z")

</div>

Small note - I would also recommend you to install `@babylonjs/materials` that you reference in some of the scripts you pasted.

On a larger note, as Jeremy said, it’s probably all because of your tsconfig . But it is hard to say without seeing the actual project code.

---

<div class="post-metadata">

### Author: ![addem](https://avatars.discourse-cdn.com/v4/letter/a/c57346/32.png) [@addem](https://forum.babylonjs.com/u/addem)
#### Post date: [September 4, 2023, 5:33pm UTC](https://forum.babylonjs.com/t/how-do-you-make-your-own-personal-library-of-scripts/43781/7 "2023-09-04T17:33:00Z")

</div>

Indeed! I’m actually not sure why it was working without that dependency … but at some point the compiler started complaining about the lack of the dependency, so I added it, and now it’s working.

Anyway, for now I actually have implemented a kind of stop-gap by just publishing an NPM package and then importing it. This feels kind of dumb, publishing a noob-level package just to get the build system to work the way I want it. But it is working in the intended ways – so at least I can continue to make progress.

After I’ve built a few more things, I’ll experiment with just doing what Jeremy said. It at least sounds smarter and more efficient. If that doesn’t work for whatever reason, I have also seen a few StackOverflow posts about how you can make local node packages, so that might work too.

Anyway, my question is basically answered, one way or another! I just don’t know exactly which answer I’m eventually going to live with, but I’m sure at least one of these solutions works.

Thanks one and all for the help!

---

<div class="post-metadata">

### Author: ![inteja](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/inteja/32/22553_2.png) [@inteja](https://forum.babylonjs.com/u/inteja)
#### Post date: [September 4, 2023, 10:09pm UTC](https://forum.babylonjs.com/t/how-do-you-make-your-own-personal-library-of-scripts/43781/8 "2023-09-04T22:09:41Z")

</div>

Maybe it helps with one of your stated issues, but in `vite.config.ts` you can also add the `@babylon` packages as external dependencies e.g. here’s what we use for libraries:

```auto
import path from "path";
import { defineConfig } from "vite";
import dts from 'vite-plugin-dts'
import packageJson from "./package.json";

const getPackageName = () => {
  return packageJson.name;
};

const getPackageNameCamelCase = () => {
  try {
    return getPackageName().replace(/-./g, (char) => char[1].toUpperCase());
  } catch (err) {
    throw new Error("Name property in package.json is missing.");
  }
};

const fileName = {
  es: `${getPackageName()}.mjs`,
  cjs: `${getPackageName()}.cjs`,
  iife: `${getPackageName()}.iife.js`,
};

const formats = Object.keys(fileName) as Array<keyof typeof fileName>;

export default defineConfig({
  base: "./",
  build: {
    lib: {
      entry: path.resolve(__dirname, "src/index.ts"),
      name: getPackageNameCamelCase(),
      formats,
      fileName: (format) => fileName[format],
    },
    rollupOptions: {
      external: [
        "@babylonjs/core",
        "@babylonjs/inspector",
        "@babylonjs/loaders",
        "@babylonjs/materials",
        "@babylonjs/serializers",
      ],
    },
  },
  plugins: [dts({ rollupTypes: true })],
});

```
