Skip to main content
bun publish packs your package into a tarball and publishes it to the configured npm registry. It strips workspace: and catalog: version protocols from package.json, resolving them to real version numbers before publishing.
Example output:

Authentication

Set an auth token via the NPM_CONFIG_TOKEN environment variable (suitable for GitHub Actions and other CI systems):
Or configure the token in bunfig.toml:
Or in .npmrc:

Flags

--access

Set the access level of the published package. Required for scoped packages that should be publicly accessible:
Unscoped packages are always public. You can also set access in publishConfig in package.json:

--tag

Publish under a specific dist-tag instead of latest:
Or in package.json:

--dry-run

Simulate the publish without actually uploading anything. Shows you exactly which files would be included:

--tolerate-republish

Exit with code 0 instead of 1 if the package version already exists in the registry. Useful in CI jobs that may be re-run:

--otp

Provide a one-time password for accounts with 2FA enabled:

--auth-type

Choose how to complete 2FA: web (default) opens a browser, legacy prompts in the terminal:

Controlling which files are published

Bun respects the "files" field in package.json and .npmignore. Only files listed in "files" (or not excluded by .npmignore) are included in the tarball.

Pack without publishing

To create the tarball without uploading it, use bun pm pack:
You can then publish the tarball separately:
When you pass a tarball path to bun publish, lifecycle scripts (prepublishOnly, prepack, prepare, postpack, publish, postpublish) are not run. Scripts only run when bun publish packs the package itself.

Lifecycle scripts during publish

When bun publish packs the package, it runs lifecycle scripts in this order:
  1. prepublishOnly
  2. prepack
  3. prepare
  4. (pack)
  5. postpack
  6. (upload)
  7. publish
  8. postpublish