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)