DEV Community

Cover image for How we test NPM packages before publishing with npm pack
Yoriiis
Yoriiis

Posted on • Edited on

How we test NPM packages before publishing with npm pack

When working on multiple interdependent NPM packages across projects, testing a new version before publishing is essential.

At Prisma Media, we maintain several packages on our private NPM registry, used directly on our websites. While each package comes with a standalone demo, we regularly need to validate development versions in real environments.


Understanding npm pack

Running npm pack builds your package locally and generates a .tgz archive identical to what would be published with npm publish. The archive is created in the current directory and includes only the files defined in the files field of your package.json or filtered by .npmignore.

It's also a convenient way to verify what your package will actually ship before publishing. Inspecting the generated archive helps ensure that only the expected files are included.

 raw `npm-pack` endraw  terminal output


Testing options

Developers have a few options to test packages locally:

  • Local linking: npm link works if both the package and consuming project are cloned locally
  • Preview or shared environments: npm link fails here. Other options include:
    • Publishing a tagged version (like beta), it requires deployment to the registry
    • Using npm pack, it generates the .tgz archive that would be published, without touching the registry

We chose npm pack for its simplicity and safety. It allows developers and product teams to test new versions in local or preview environments, without affecting production workflows.


Implementation

Our package pipelines follow a standard sequence: install, build, test, pack and finally deploy.

For details on our reusable GitLab CI template you can read

The npm pack job is manual. When a developer needs a dev version:

  1. Navigate to the latest pipeline of the merge request
  2. Trigger the npm-pack job
  3. The job runs and uploads the TGZ as an artifact
  4. Install and test locally:
  • Download and extract the artifact
  • Install the TGZ in your project:
   npm install <path_to_tgz_file>
Enter fullscreen mode Exit fullscreen mode
  • This replaces the version from the registry with the local TGZ version. Example diff:
   - "player": "1.0.0"
   + "player": "file:player-1.1.0.tgz"
Enter fullscreen mode Exit fullscreen mode
  • Commit the TGZ file to your branch if you plan to deploy a preview
  • Once committed, the CI will install the TGZ

GitLab CI template

Here is a simplified .gitlab-ci.yml template for the npm-pack job:

npm-pack:
  variables:
    PACKAGES_DIR: 'npm-pack-packages'
  image: node:22-alpine
  script:
    - mkdir $PACKAGES_DIR
    - PACKAGE_TGZ=$(npm pack)
    - mv "$PACKAGE_TGZ" $PACKAGES_DIR
  artifacts:
    paths:
      - $PACKAGES_DIR
  when: manual
Enter fullscreen mode Exit fullscreen mode

This job generates the TGZ locally and stores it as an artifact. The file can then be installed for local or preview testing.

For the GitHub Actions equivalent

Discover npm-pack workflow examples on GitHub

Advantages

  • Developers can test packages locally without publishing
  • The TGZ can be versioned in the dev branch, allowing CI to install it on preview environments
  • Product teams can validate features before merging

⚠️ Remember: TGZ files are for development and preview only, never for production.


Key points

  • npm pack replaces npm link for shared or CI environments
  • When switching back to a registry version, always run npm uninstall <package> before reinstalling
  • Version TGZ files only for temporary testing; never use them in production
  • CI pipelines can safely produce TGZ artifacts for local or preview testing
  • Manual triggering keeps pipelines efficient

Conclusion

Using npm pack to test packages locally or in preview environments simplifies cross-project development. It sits between local linking and full registry publishing, giving developers and product teams a faster way to validate changes.

By integrating this workflow into CI, we can safely validate packages, maintain developer productivity and ensure quality before official publication.

The complete example is available on GitHub for you to try out! 🧑‍💻

Discover NPM pack on GitHub


Resources


Top comments (0)