NPM Publish
ActionsTags
(2)Publish packages to npm automatically in GitHub Actions whenever a change to your package'sversion
field is detected.
This action automates a specific kind of continuous deployment tonpm
, where you want to publish whenever theversion
field inpackage.json
changes on yourmain
branch. If you prefer to publish on tags (for example, those created by thenpm version
command), or are using an alternative package manager likepnpm
, you don't need this action! Simply configuresetup-node
with itsregistry-url
option and call your package manager'spublish
command directly. This is more secure than relying on a third-party action like this one, and is more customizable.
# Publish to npm whenever a tag is pushedname:Publish to npmon:push:tags:v*jobs:build:runs-on:ubuntu-latestpermissions:contents:readid-token:writesteps: -uses:actions/checkout@v5 -uses:actions/setup-node@v5with:node-version:"24"registry-url:"https://registry.npmjs.org" -run:npm ci -run:npm test -run:npm publish --provenance --ignore-scriptsenv:NODE_AUTH_TOKEN:${{ secrets.NPM_TOKEN }}
See GitHub'sNode.js publishing guide and npm'strusted publishing docs for more details and examples.
🧠SmartOnly publishes if the version number in
package.json
differs from the latest on npm.🛠ConfigurableCustomize the version-checking behavior, the registry URL, and path of your package.
🔐SecureKeeps your npm authentication token secret. Doesn't read nor write to
~/.npmrc
.⚡Fast100% JavaScript (which is faster than Docker) and bundled to optimize loading time.
📤OutputsExposes the old and new version numbers, and the type of change (major, minor, patch, etc.) as variables that you can use in your workflow.
This package can be used three different ways:
🤖 AGitHub Action as part of your CI/CD process
🧩 Afunction that you call in your JavaScript code
🖥 ACLI that you run in your terminal
To use the GitHub Action, you'll need to add it as a step in yourworkflow file. By default, the only thing you need to do is set thetoken
parameter to yournpm authentication token.
on:push:branches:mainjobs:publish:runs-on:ubuntu-lateststeps: -uses:actions/checkout@v5 -uses:actions/setup-node@v5with:node-version:"24" -run:npm ci -run:npm test -uses:JS-DevTools/npm-publish@v4with:token:${{ secrets.NPM_TOKEN }}
If you havetrusted publishing configured for your package and usenpm@>=11.5.1
, you can omit thetoken
input and use OIDC instead.
Important
If you're publishing a private package, you will still need to provide a read-onlytoken
so the action can read existing versions from the registry before publish.
jobs: publish: runs-on: ubuntu-latest+ permissions:+ contents: read+ id-token: write # required to use OIDC steps: - uses: actions/checkout@v5 - uses: actions/setup-node@v5 with: node-version: "24" # includes npm@11.6.0 - run: npm ci - run: npm test - uses: JS-DevTools/npm-publish@v4- with:- token: ${{ secrets.NPM_TOKEN }}
You can also publish to third-party registries. For example, to publish to theGitHub Package Registry, settoken
tosecrets.GITHUB_TOKEN
andregistry
tohttps://npm.pkg.github.com
:
on:push:branches:mainjobs:publish:runs-on:ubuntu-latestpermissions:contents:readpackages:write# allow GITHUB_TOKEN to publish packagessteps: -uses:actions/checkout@v5 -uses:actions/setup-node@v5with:node-version:"24" -run:npm ci -run:npm test -uses:JS-DevTools/npm-publish@v4with:token:${{ secrets.GITHUB_TOKEN }}registry:"https://npm.pkg.github.com"
You can set any or all of the following input parameters usingwith
:
Name | Type | Default | Description |
---|---|---|---|
token | string | unspecified | Registry authentication token, not required if usingtrusted publishing³ |
registry ¹ | string | https://registry.npmjs.org/ | Registry URL to use. |
package | string | Current working directory | Path to a package directory, apackage.json , or a packed.tgz to publish. |
tag ¹ | string | latest | Distribution tag to publish to. |
access ¹ | public ,restricted | npm defaults | Whether the package should be publicly visible or restricted. |
provenance ¹ ² | boolean | false | Runnpm publish with the--provenance flag to addprovenance statements. |
strategy | all ,upgrade | all | Useall to publish all unique versions,upgrade for only semver upgrades. |
ignore-scripts | boolean | true | Runnpm publish with the--ignore-scripts flag as a security precaution. |
dry-run | boolean | false | Runnpm publish with the--dry-run flag to prevent publication. |
- May be specified using
publishConfig
inpackage.json
. - Provenance requires npm
>=9.5.0
. - Trusted publishing npm
>=11.5.1
and must be run from a supported cloud provider.
npm-publish exposes several output variables, which you can use in later steps of your workflow if you provide anid
for the npm-publish step.
steps: - uses: JS-DevTools/npm-publish@v4+ id: publish with: token: ${{ secrets.NPM_TOKEN }}+ - if: ${{ steps.publish.outputs.type }}+ run: echo "Version changed!"
Name | Type | Description |
---|---|---|
id | string | Package identifier of the release:${name}@${version} or empty if no release. |
type | string | Semver release type,initial if first release,different if other change, or empty if no release. |
name | string | Name of the package. |
version | string | Version of the package. |
old-version | string | Previously published version ontag or empty if no previous version on tag. |
tag | string | Distribution tag the package was published to. |
access | string | Access level the package was published with, ordefault if scoped-package defaults were used. |
registry | string | Registry the package was published to. |
dry-run | boolean | Whethernpm publish was run in "dry run" mode. |
To use npm-package in your JavaScript code, you'll need to install it usingnpm or other package manager of choice:
npm install --save-dev @jsdevtools/npm-publish
You can then import it and use it in your code like this:
import{npmPublish}from"@jsdevtools/npm-publish";// Run npm-publish with all defaultsawaitnpmPublish({token:"YOUR_NPM_AUTH_TOKEN_HERE"});
As shown in the example above, you should pass an options object to thenpmPublish
function. In TypeScript, theOptions
interface is available as an import.
importtype{Options}from"@jsdevtools/npm-publish";
Name | Type | Default | Description |
---|---|---|---|
token | string | required | Registry authentication token, not required if usingtrusted publishing³ |
registry ¹ | string,URL | https://registry.npmjs.org/ | Registry URL to use. |
package | string | Current working directory | Path to a package directory, apackage.json , or a packed.tgz to publish. |
tag ¹ | string | latest | Distribution tag to publish to. |
access ¹ | public ,restricted | npm defaults | Whether the package should be publicly visible or restricted. |
provenance ¹ ² | boolean | false | Runnpm publish with the--provenance flag to addprovenance statements. |
strategy | all ,upgrade | all | Useall to publish all unique versions,upgrade for only semver upgrades. |
ignoreScripts | boolean | true | Runnpm publish with the--ignore-scripts flag as a security precaution. |
dryRun | boolean | false | Runnpm publish with the--dry-run flag to prevent publication. |
logger | object | undefined | Logging interface withdebug ,info , anderror log methods. |
temporaryDirectory | string | os.tmpdir() | Temporary directory to hold a generated.npmrc file |
- May be specified using
publishConfig
inpackage.json
. - Provenance requires npm
>=9.5.0
. - Trusted publishing npm
>=11.5.1
and must be run from a supported cloud provider.
ThenpmPublish()
function returns a promise of aResults
object. In TypeScript, theResults
interface is available as an import.
importtype{Results}from"@jsdevtools/npm-publish";
Name | Type | Description |
---|---|---|
id | Optional string | Package identifier of the release:${name}@${version} orundefined if no release. |
type | Optional string | Semver release type,initial if first release,different if other change, orundefined if no release. |
name | string | Name of the package. |
version | string | Version of the package. |
oldVersion | Optional string | Previously published version ontag orundefined if no previous version. |
tag | string | Distribution tag that the package was published to. |
access | Optional string | Access level the package was published with, orundefined if scoped-package defaults were used. |
registry | URL | Registry the package was published to. |
dryRun | boolean | Whethernpm publish was run in "dry run" mode. |
You can also usenpm-publish
as a command-line tool in your terminal.
npm install --save-dev @jsdevtools/npm-publish
You can then use it in your terminal or innpm run
scripts.
npx npm-publish --token YOUR_NPM_AUTH_TOKEN_HERE
You can customize your call with options to change the registry, package, etc.
npx npm-publish --token YOUR_NPM_AUTH_TOKEN_HERE --registry http://example.com ./path/to/package
Runnpm-publish --help
to see the full list of options available.
Usage: npm-publish <options> [package]Arguments: package The path to the package to publish. May be a directory, package.json, or .tgz file. Defaults to the package in the current directory.Options: --token <token> npm authentication token. Not required if using trusted publishing. See npm documentation for details. --registry <url> Registry to read from and write to. Defaults to "https://registry.npmjs.org/". --tag <tag> The distribution tag to check against and publish to. Defaults to "latest". --access <access> Package access, may be "public" or "restricted". See npm documentation for details. --provenance Publish with provenance statements. See npm documentation for details. --strategy <strategy> Publish strategy, may be "all" or "upgrade". Defaults to "all", see documentation for details. --no-ignore-scripts Allow lifecycle scripts, which are disabled by default as a security precaution. Defaults to false. --dry-run Do not actually publish anything. --quiet Only print errors. --debug Print debug logs. -v, --version Print the version number. -h, --help Show usage text.Examples: $ npm-publish --token abc123 ./my-package
Major releases of the action and libraries may contain breaking changes, documented here.For more detailed change logs, seereleases.
Thev4
release does not require any changes to how you use thenpm-publish
action fromv3
. The action was updated to Node 24 / npm 11.
In the library and CLI, support for Node 16 and Node 18 was dropped inv4
, and the library API was switched to ESM-only. Library users should switch to ESM or update Node to a version with support forloading ES modules usingrequire
.
Thev4
release does not require any changes to how you use thenpm-publish
action fromv2
. The action was updated to Node 20 inv3
due to GitHub Action'sdeprecation of Node 16, and then updated to Node 24 inv4
.
In the library and CLI, support for Node 16 and Node 18 was dropped inv4
, and the library API was switched to ESM-only. Library users should switch to ESM or update Node to a version with support forloading ES modules usingrequire
.
The v2 release made several breaking changes to inputs, outputs, and behaviors that were present inv1
. The examples below focus on the action, but the same changes are applicable to the library and CLI, too.
In the library and CLI, support for Node 16 and Node 18 was dropped inv4
, and the library API was switched to ESM-only. Library users should switch to ESM or update Node to a version with support forloading ES modules usingrequire
.
Thecheck-version
andgreater-version-only
boolean options were replaced with thestrategy
option:
strategy: all
(default) will publish any version that does not yet exist in the registrystrategy: upgrade
will publish only if the version is a semver upgrade of the requesteddist-tag
with: token: ${{ secrets.NPM_TOKEN }}- check-version: true- greater-version-only: false+ strategy: all with: token: ${{ secrets.NPM_TOKEN }}- check-version: true- greater-version-only: true+ strategy: upgrade
check-version: false
has been removed. If you only need to publish, without first checking whether the version exists in the registry, you canusenpm
directly instead:
- uses: actions/setup-node@v5 with: node-version: '24'+ registry-url: https://registry.npmjs.org/- - uses: JS-DevTools/npm-publish@v1- with:- token: ${{ secrets.NPM_TOKEN }}- check-version: false+ - run: npm publish+ env:+ NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
Thetype
output is now an empty string instead of'none'
when no release occurs
- run: echo "Version changed!"- if: ${{ steps.publish.outputs.type != 'none' }}+ if: ${{ steps.publish.outputs.type }}
The--ignore-scripts
option is now passed tonpm publish
as a security precaution. If you define any publish lifecycle scripts -prepublishOnly
,prepack
,prepare
,postpack
,publish
,postpublish
- we recommend you run that logic as a separate explicit build step.
+ - run: npm run build- - uses: JS-DevTools/npm-publish@v1+ - uses: JS-DevTools/npm-publish@v4 with: token: ${{ secrets.NPM_TOKEN }}
If you can't change your build, you can set theignore-scripts
input tofalse
as a workaround. Be aware that failures during a lifecycle script can be difficult to debug, and anystdout
/stderr
output from your build script could interfere with hownpm-publish
interprets results from thenpm
CLI.
- - uses: JS-DevTools/npm-publish@v1+ - uses: JS-DevTools/npm-publish@v4 with: token: ${{ secrets.NPM_TOKEN }}+ ignore-scripts: false
The global.npmrc
file is no longer read nor modified. This means thetoken
option is now required for the library and CLI. (It was already required for the action.) You may have workarounds in place referencingINPUT_TOKEN
, which v1erroneously wrote to.npmrc
. These workarounds should be removed.
- uses: actions/setup-node@v5 with: node-version: '24' registry-url: https://registry.npmjs.org/- - uses: JS-DevTools/npm-publish@v1+ - uses: JS-DevTools/npm-publish@v4 with: token: ${{ secrets.NPM_TOKEN }} - name: Do some more stuff with npm run: npm whoami env:- INPUT_TOKEN: ${{ secrets.NPM_TOKEN }}+ NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
npm-publish is 100% free and open-source, under theMIT license. Use it however you want.
This package isTreeware. If you use it in production, then we ask that youbuy the world a tree to thank us for our work. By contributing to the Treeware forest you’ll be creating employment for local families and restoring wildlife habitats.
Thanks to these awesome companies for their support of Open Source developers ❤
NPM Publish is not certified by GitHub. It is provided by a third-party and is governed by separate terms of service, privacy policy, and support documentation.
Tags
(2)NPM Publish is not certified by GitHub. It is provided by a third-party and is governed by separate terms of service, privacy policy, and support documentation.