Publishing to GitHub and npm
This guide describes the recommended workflow for publishing packages to GitHub and npm.
Prerequisites
Before publishing, ensure you have:
- Authentication with npm: Run
npm loginif not already authenticated - Your changes merged into the main branch (or
masterdepending on your repository) - All tests passing and changes committed
Commit Your Changes
Make your changes and commit them:
git add .
git commit -m "Add new feature"
It's generally best to run npm version after merging your feature branch into the main branch. This ensures that the version bump and tag are applied to the final state of the code that will be released.
Understanding Version Numbers
Choose the appropriate version number according to Semantic Versioning (SemVer):
- Patch (e.g.,
1.0.0→1.0.1): Bug fixes and minor changes - Minor (e.g.,
1.0.0→1.1.0): New features, backward compatible - Major (e.g.,
1.0.0→2.0.0): Breaking changes - Pre-release (e.g.,
1.0.0-beta.1): Beta or alpha versions
Version Command Syntax
The basic command structure is:
npm version <newversion> -m "Bump version to %s"
The %s in the command is a placeholder that npm automatically replaces with the new version number. For example:
npm version 1.1.0 -m "Bump version to %s"
This command automatically:
- Updates
package.jsonto the new version - Creates a Git commit with your message
- Creates a Git tag matching the version (e.g.,
v1.1.0)
Beta Release Workflow
Use this workflow when publishing a pre-release version for testing:
npm version 1.0.0-beta.1 -m "Bump version to %s"
git push origin main --tags
npm publish --tag beta
Replace main with master if your repository uses the older branch naming convention.
How the Beta Release Works
-
npm version 1.0.0-beta.1 -m "Bump version to %s"- Updates
package.jsonto"version": "1.0.0-beta.1" - Creates a Git commit with the message
"Bump version to 1.0.0-beta.1", including changes topackage.json(andpackage-lock.jsonif present) - Creates a Git tag
v1.0.0-beta.1pointing to this commit - Standard Compliance: Uses a Semantic Versioning (SemVer) pre-release identifier (
-beta.1), which is the standard for beta releases
- Updates
-
git push origin main --tags- Pushes the commit and the Git tag (
v1.0.0-beta.1) to the remote repository - Standard Compliance: Ensures the version history and tags are synchronized with the remote repository, a common practice for release tracking
- Pushes the commit and the Git tag (
-
npm publish --tag beta- Publishes the package version
1.0.0-beta.1to the npm registry with thebetatag - Ensures
npm install <package>does not install this beta version by default (it installs thelatesttagged version instead) - Users can install the beta with
npm install <package>@betaornpm install <package>@1.0.0-beta.1 - Standard Compliance: Using a custom tag like
betafor pre-release versions is the recommended npm practice to avoid breaking users who rely on stable versions
- Publishes the package version
Result: Users get the stable version with npm install <package>, and beta testers can opt in with npm install <package>@beta. This is fully aligned with npm and Git best practices.
Stable Release Workflow
Use this workflow when publishing a stable version:
npm version 1.0.0 -m "Bump version to %s"
git push origin main --tags
npm publish
Replace main with master if your repository uses the older branch naming convention.
How the Stable Release Works
-
npm version 1.0.0 -m "Bump version to %s"- Updates
package.jsonto"version": "1.0.0" - Creates a Git commit with the message
"Bump version to 1.0.0" - Creates a Git tag
v1.0.0 - Standard Compliance: Follows SemVer for stable releases and creates a clear version marker in Git
- Updates
-
git push origin main --tags- Pushes the commit and tag (
v1.0.0) to the remote repository - Standard Compliance: Keeps the remote repository in sync, standard for release workflows
- Pushes the commit and tag (
-
npm publish- Publishes version
1.0.0to the npm registry with the defaultlatesttag - Makes this version the default for
npm install <package> - Standard Compliance: Assigning the
latesttag to stable releases is the npm standard, ensuring users get the latest stable version by default
- Publishes version
Result: The stable version 1.0.0 is installed by default with npm install <package>, following npm's expected behavior.
Installing Versions
Installing the Latest Stable Version
To install the latest stable version (default behavior):
npm install <package>
This installs the version tagged as latest on the npm registry.
Installing a Beta Version
To install the latest beta version:
npm install <package>@beta
This installs the latest version tagged as beta on the npm registry (e.g., 1.0.0-beta.1).
Installing a Specific Version
To install a specific version by exact version number:
npm install <package>@1.0.0
npm install <package>@1.0.0-beta.1
Checking Available Versions
To list all available versions and their tags:
npm view <package> versions
npm dist-tag ls <package>
The npm dist-tag ls command shows which tags (like latest and beta) point to which versions, helpful for understanding what's available.
Updating an Installed Package
If you already have the package installed and want to update to a different version:
npm update <package> # Updates to the latest minor/patch of current major version
npm install <package>@1.0.0 # Installs a specific version
npm install <package>@beta # Updates to the latest beta version
Summary
- Beta Workflow: Using
npm publish --tag betaensures beta versions (e.g.,1.0.0-beta.1) are available only to users who explicitly request them, protecting users who rely on thelateststable version - Stable Workflow: Publishing without a tag automatically uses the
latesttag, making the version available to all users by default - Git Integration: Both workflows use
npm versionto synchronizepackage.jsonwith Git commits and tags, which is a standard practice for Node.js projects - SemVer Compliance: Using
1.0.0-beta.1for betas and1.0.0for stable releases adheres to Semantic Versioning standards - User Experience: The distinction between
latest(stable) andbetatags ensures a clear separation, which is a best practice for package maintainers