How to Prerelease an NPM Package: A Practical Approach

17 March 2025

npm

1. Why Prerelease?

Recently, we implemented the modularization of our frontend infrastructure at Ahamove, covering areas like system design, UI components, and ESLint configuration. This shift introduced a critical need for testing different versions before stable releases. Releasing alpha and beta versions allows us to:

  • Validate changes without affecting production dependencies.
  • Gather feedback from internal teams before a full rollout.
  • Avoid unnecessary version increments in the stable release cycle.

Luckily, I came across a solid approach to managing prereleases effectively. Here’s how we do it.


2. Understanding NPM Prerelease Versions

NPM follows Semantic Versioning (SemVer), which defines version numbers in the format:

MAJOR.MINOR.PATCH-PRERELEASE.BUILD
  • MAJOR: Breaking changes (1.0.0 → 2.0.0)
  • MINOR: New features without breaking changes (1.2.0 → 1.3.0)
  • PATCH: Bug fixes (1.2.1 → 1.2.2)
  • PRERELEASE: Indicates alpha, beta, or release candidates (1.2.0-alpha.1)

Examples of prerelease versions:

  • 1.2.0-alpha.1 → First alpha release.
  • 1.2.0-beta.3 → Third beta release.
  • 1.2.0-rc.1 → First release candidate.

Key Differences from Stable Versions

  • Prerelease versions are considered lower precedence than stable versions.
  • Users must explicitly install them (npm install package@beta).

3. Creating the Prerelease Version

How npm version Works

When bumping the version number of an npm package, the npm version command automatically updates both package.json and package-lock.json, creates a Git commit, and tags the repository with the new version. It follows Semantic Versioning (SemVer).

You can control how the version is incremented based on the type of release.

Regular Versions

npm version major   # changes 0.1.2 to 1.0.0
npm version minor   # changes 0.1.2 to 0.2.0
npm version patch   # changes 0.1.2 to 0.1.3

Prerelease Versioning

Semantic Versioning allows prerelease versions using a hyphen (-). For example, a typical release cycle of alpha → beta → production could look like:

  • 1.0.0-alpha
  • 1.0.0-beta
  • 1.0.0

However, for iterative releases, we append a version number to track multiple versions:

  • 1.0.0-alpha.3 → Third alpha release.
  • 1.0.0-beta.5 → Fifth beta release.

Examples of Creating Prerelease Versions

Alpha Versions

npm version premajor --preid=alpha # changes 0.1.2 to 2.0.0-alpha.0
npm version preminor --preid=alpha # changes 0.1.2 to 0.2.0-alpha.0
npm version prepatch --preid=alpha # changes 0.1.2 to 0.1.3-alpha.0

Beta Versions

npm version premajor --preid=beta # changes 0.1.2 to 2.0.0-beta.0
npm version preminor --preid=beta # changes 0.1.2 to 0.2.0-beta.0
npm version prepatch --preid=beta # changes 0.1.2 to 0.1.3-beta.0

Incrementing Prerelease Versions

npm version prerelease # changes 1.0.0-alpha.0 to 1.0.0-alpha.1

4. Tagging and Publishing Prerelease Versions

To publish a prerelease, follow these steps:

1. Bump Version with a Prerelease Tag

Use npm version to set up a new prerelease version:

npm version prepatch --preid=alpha  # 1.2.1-alpha.0
npm version prerelease --preid=beta  # 1.2.1-beta.1

Alternatively, manually specify the version:

npm version 1.2.1-beta.2

2. Publish to NPM with a Dist Tag

By default, npm publish pushes the package as latest. Instead, use a tag to avoid impacting production users:

npm publish --tag alpha
npm publish --tag beta

This ensures that when users run:

npm install my-package

They get the latest stable version and not the prerelease.

To install a prerelease, users must explicitly run:

npm install my-package@beta

3. Manage Dist Tags

Check available tags:

npm dist-tag ls my-package

Move a prerelease to latest when ready:

npm dist-tag add my-package@1.2.1 latest

5. Conclusion

Using NPM prerelease versions helps maintain a structured testing process, preventing unwanted production updates. By leveraging alpha/beta releases and dist tags, we:

  • Safely test new features before stable releases.
  • Give internal teams a way to try out changes.
  • Reduce versioning noise in production dependencies.

This approach has streamlined our frontend modularization, ensuring smoother rollouts of UI components, system configs, and shared libraries.

If you’re managing a frontend package, give this workflow a try!

(Thanks to Scott Vandehey for his insightful article on How to Prerelease an NPM Package)