Reusable browser and Node.js helpers are easier to test when they are shaped as npm packages instead of copied between projects. A small package needs metadata, one public entry point, and a consumer check that proves another project can import it.
npm init creates the initial package.json, while npm pkg set records the fields that control package identity and module loading. An ES module entry point with exports lets consumers import only the public file.
Local testing should happen before publishing to the registry. Installing the packed .tgz file into a separate consumer project catches missing files, the wrong module type, and broken exports before any release step is considered.
$ mkdir format-title
$ cd format-title
$ npm init --yes Wrote to package.json: ##### snipped #####
$ npm pkg set name=format-title version=1.0.0 description="Format display titles" type=module exports=./index.js
type=module tells Node.js to treat .js files as ES modules. The exports field exposes index.js as the package's public entry point.
$ npm pkg set 'files=["index.js"]' --json
The files field keeps local tests, notes, and build artifacts out of the package unless they are deliberately included.
$ npm pkg get name version type exports --json
{
"name": "format-title",
"version": "1.0.0",
"type": "module",
"exports": "./index.js"
}
export function formatTitle(value) { return value .trim() .toLowerCase() .replace(/\b[a-z]/g, (letter) => letter.toUpperCase()); }
$ npm pack npm notice Tarball Contents npm notice 145B index.js npm notice 327B package.json npm notice filename: format-title-1.0.0.tgz ##### snipped ##### format-title-1.0.0.tgz
$ cd ..
$ mkdir format-title-consumer
$ cd format-title-consumer
$ npm init --yes Wrote to package.json: ##### snipped #####
$ npm install ../format-title/format-title-1.0.0.tgz added 1 package in 205ms
import { formatTitle } from "format-title"; console.log(`Imported formatTitle(): ${formatTitle(" release NOTES ")}`);
$ node demo.mjs Imported formatTitle(): Release Notes
$ cd ..
$ rm -r format-title-consumer format-title/format-title-1.0.0.tgz
Keep the consumer directory if it should become a permanent integration fixture.