Guide: Using Local Private NPM Packages in Your Team
This guide targets team-internal libraries (utils/ui/core, etc.) that are not publicly published. It explains how to use local, private packages in ArenaPro projects without pushing them to a public registry.
When should you use a local package?
- You have reusable libraries shared across multiple maps/projects, but you don’t want to expose them publicly.
- You want fast iteration and validation without a full publish workflow.
- You need a reproducible installation process in CI/CD, while avoiding dependency on public registries.
Option 1: file:
dependency (simple and stable)
If your package folder sits nearby your project, point to it in your project’s package.json
via file:
.
- Example structure:
my-project/ # your ArenaPro project
../my-utils/ # your local package (a sibling folder)
- Declare the dependency in
my-project/package.json
:
{
"name": "my-project",
"type": "module",
"dependencies": {
"my-utils": "file:../my-utils"
}
}
- Install dependencies:
npm install
After installation, node_modules/my-utils
will be a local link to ../my-utils
(not downloaded from the internet).
- Use it in code:
// client/src/index.ts
import { clampToRange } from "my-utils";
export function heal(player, amount) {
const hp = player.getData("hp");
player.setData("hp", clampToRange(hp + amount, 0, 100));
}
- Pros: Simple, stable, works across platforms; CI/CD friendly.
- Cons: When editing
../my-utils
, you might need to restart the build or reinstall if caches don’t pick up changes.
Tip: In your local package, set
"sideEffects": false
and export as ESM to enable better tree-shaking.
Option 2: npm pack
+ install tarball
When you want to validate your package under conditions close to a real publish (e.g., ignored files, build outputs, exports
field), package it into a tarball and install it.
- In the local package directory:
npm pack
This generates a tarball like my-utils-1.0.0.tgz
.
- Install the tarball in the project directory:
npm install ../my-utils/my-utils-1.0.0.tgz
- Pros: Very close to real publish behavior; ideal for pre-publish self-testing.
- Cons: You need to repack and reinstall after each change.
FAQ
Import fails:
ERR_MODULE_NOT_FOUND
- Check that
exports
/main
point to actual built outputs. - Ensure
type: "module"
and ESM entry are consistent.
- Check that
ESM/CJS incompatibility:
require is not defined
orCannot use import statement outside a module
- Standardize on ESM output, or provide both ESM/CJS via
exports
and prefer ESM in the project.
- Standardize on ESM output, or provide both ESM/CJS via
Edits in the local package don’t take effect immediately
- With
file:
: restart the build or reinstall; clear bundler caches. - With
npm pack
: re-runnpm pack
and reinstall the new.tgz
in the project.
- With
Missing types: editor cannot find
.d.ts
- Add
"types": "dist/index.d.ts"
inpackage.json
and ensure the file exists.
- Add
Which option should I choose?
- Prefer
file:
for simple, stable, and out-of-the-box workflows. - Prefer
npm pack
+ tarball installation for pre-publish validation and CI/CD reproducibility.
For distributed teams, non-co-located folders, or advanced access control, consider a private registry (e.g., Verdaccio / GitHub Packages / GitLab Package Registry). That follows a “private publish” route and is out of scope for this page.