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.
Steps to create a JavaScript package with npm:
- Create the package directory.
$ mkdir format-title
- Enter the package directory.
$ cd format-title
- Create the initial package metadata.
$ npm init --yes Wrote to package.json: ##### snipped #####
- Set the package identity and public module entry point.
$ 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.
- Limit the files included in the package tarball.
$ 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.
- Check the saved package metadata.
$ npm pkg get name version type exports --json { "name": "format-title", "version": "1.0.0", "type": "module", "exports": "./index.js" } - Create the exported package entry point.
- index.js
export function formatTitle(value) { return value .trim() .toLowerCase() .replace(/\b[a-z]/g, (letter) => letter.toUpperCase()); }
- Pack the package into a local tarball.
$ 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
- Return to the parent directory.
$ cd ..
- Create a separate consumer project.
$ mkdir format-title-consumer
- Enter the consumer project.
$ cd format-title-consumer
- Create the consumer project metadata.
$ npm init --yes Wrote to package.json: ##### snipped #####
- Install the packed package into the consumer project.
$ npm install ../format-title/format-title-1.0.0.tgz added 1 package in 205ms
- Create the consumer smoke test.
- demo.mjs
import { formatTitle } from "format-title"; console.log(`Imported formatTitle(): ${formatTitle(" release NOTES ")}`);
- Run the consumer smoke test.
$ node demo.mjs Imported formatTitle(): Release Notes
- Return to the parent directory.
$ cd ..
- Remove the temporary consumer project and packed tarball.
$ 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.
Mohd Shakir Zakaria is a cloud architect with deep roots in software development and open-source advocacy. Certified in AWS, Red Hat, VMware, ITIL, and Linux, he specializes in designing and managing robust cloud and on-premises infrastructures.