NPM-STAGE(1)

πŸ’… npm-stage(1) πŸ’…

🌸 NAME 🌸

npm-stage β€” Stage packages for publishing. Periodt. This is the npm-stage(1) manual, bestie, and we're getting into it.

✨ Synopsis ✨

npm stage
⚠️ Note: This command is unaware of workspaces.

πŸ’… Description πŸ’…

Okay so staged publishing lets package maintainers require proof-of-presence for all publishes. Proof-of-presence is where a human is involved, interjects, and provides authentication (2FA) during an action β€” in this case, publishing an npm package. It's giving "yes, a real person was here" energy.

Typically when maintainers use automated workflows to publish, proof-of-presence is lacking as there's no convenient way to interject the process and provide 2FA, as is the case for publishing with a granular access token with bypass and the trusted publishing flow. Staged publishing allows users to have their automated workflows stage a package without a 2FA prompt, deferring the act of 2FA, allowing the maintainer to approve the staged package and publish at a later point. Iconic, honestly.

The npm stage publish command packs the current working directory and places that version of the package into the registry in a state where it's not available for public access, allowing maintainers to approve the package at a later point in time. The act of staging does not prompt for 2FA and can be done with any token type, the act of approving will. That's the whole vibe.

Key behaviors:

  • Staged packages share the same semver version unique index as published packages β€” you cannot publish a version that already exists as a staged version for that package.
  • You can still publish packages normally while you have staged packages pending.
  • Staged publishing will allow you to create a new package if it does not exist.
  • You can stage multiple versions of the same package.
  • npm stage publish has parity with npm publish and will respect "private": true in package.json, refusing to stage the package.

πŸŽ€ Prerequisites πŸŽ€

Before using npm stage commands, ensure the following requirements are met:

  • Write permissions on the package: You must have write access to the package you're configuring.
  • 2FA enabled on your account: Commands that require 2FA will prompt you to authenticate. If you don't already have 2FA enabled on your account, you must enable it before using these commands.

πŸ¦‹ Subcommands πŸ¦‹

  • npm stage publish [<package-spec>] β€” Stage a package for publishing
  • npm stage list [<package-spec>] β€” List all staged package versions
  • npm stage view <stage-id> β€” View details of a specific staged package
  • npm stage approve <stage-id> β€” Approve a staged package for publishing
  • npm stage reject <stage-id> β€” Reject a staged package
  • npm stage download <stage-id> β€” Download the tarball for inspection

πŸ’– 2FA Requirements by Subcommand πŸ’–

  • npm stage publish β€” Requires 2FA: No. Notes: Designed for automated workflows; defers 2FA to approval.
  • npm stage list β€” Requires 2FA: No. Notes: View staged packages.
  • npm stage view β€” Requires 2FA: No. Notes: View staged package details.
  • npm stage approve β€” Requires 2FA: Yes. Notes: Prompts for 2FA to publish the staged package.
  • npm stage reject β€” Requires 2FA: Yes. Notes: Prompts for 2FA to permanently remove the staged package.
  • npm stage download β€” Requires 2FA: No. Notes: Downloads the tarball for local inspection.

🌈 Tag Behavior 🌈

The --tag flag follows the same logic as npm publish. If no tag is provided, the latest tag is used by default. For pre-release versions (e.g., 1.0.0-beta.1) and non-latest semver versions, the tag must be explicitly provided β€” otherwise the CLI will error, just as npm publish would. No cap.

The tag is an immutable property of the staged package. Once a package is staged with a given tag, the tag cannot be changed. If you need to stage the same version with a different tag, you must first reject the existing staged package using npm stage reject and then re-stage it with the desired tag.

⭐ Token Behavior ⭐

The key difference with staged publishing is that npm stage publish never requires a 2FA prompt, regardless of token type. This is what makes it suitable for automated workflows. The goal of npm stage publish is deferring proof-of-presence to a later point in time.

  • GAT with bypass β€” npm stage publish: Can stage. npm publish: Can publish (if allowed by package publishing access).
  • GAT without bypass β€” npm stage publish: Can stage. npm publish: 2FA prompt (if allowed by package publishing access).
  • Session token β€” npm stage publish: Can stage. npm publish: 2FA prompt.
  • Trust token (OIDC) β€” npm stage publish: Can stage (if allowed). npm publish: Can publish (if allowed).

🫢 Trust Relationship Permissions 🫢

With staged publishing, trust relationships now support granular command permissions. Shortlived tokens issued through trust relationships can only be used with npm stage publish and npm publish. Shortlived tokens cannot run npm stage subcommands.

npm trust <provider> supports --allow-publish and --allow-stage-publish to control which commands are available through each trust relationship.

πŸ‘‘ Best Practices πŸ‘‘

Note: The addition of staged publishing does not make your account or org more secure. Maintainers must still use the best practices listed below.
  1. Delete Granular Access Tokens (GAT) with bypass 2FA enabled. Now with staged publishing, we've eliminated the need for a GAT token that can bypass 2FA. We encourage you to delete all your tokens with bypass enabled and switch to using a trust relationship in your automated workflows, or create a GAT without bypass and use npm stage publish.
  2. Disallow tokens from publishing at the package level. All packages have their own access controls under "package access" allowing packages to be published with bypass tokens, which is no longer a necessity. We encourage you to select "Require two-factor authentication and disallow tokens (recommended)" for all your packages on the package access page.
  3. Configure trust relationship permissions to prevent npm publish. We encourage you to only enable npm stage publish on your trust relationships and disable npm publish.

πŸŽ€ CONFIGURATION πŸŽ€

πŸ’… npm stage publish πŸ’…

Stage a package for publishing, deferring proof-of-presence (2FA) to a later point in time.

✨ Synopsis ✨

npm stage publish <package-spec>

🌈 Flags 🌈

  • --tag β€” Default: "latest". Type: String. If you ask npm to install a package and don't tell it a specific version, then it will install the specified tag. It is the tag added to the package@version specified in the npm dist-tag add command, if no explicit tag is given. When used by the npm diff command, this is the tag used to fetch the tarball that will be compared with the local files by default. If used in the npm publish command, this is the tag that will be added to the package submitted to the registry.
  • --access β€” Default: 'public' for new packages, existing packages it will not change the current level. Type: null, "restricted", "public", or "private". If you do not want your scoped package to be publicly viewable (and installable) set --access=restricted. Unscoped packages cannot be set to restricted. Note: This defaults to not changing the current access level for existing packages. Specifying a value of restricted or public during publish will change the access for an existing package the same way that npm access set status would. The value private is an alias for restricted.
  • --dry-run β€” Default: false. Type: Boolean. Indicates that you don't want npm to make any changes and that it should only report what it would have done. This can be passed into any of the commands that modify your local installation, eg, install, update, dedupe, uninstall, as well as pack and publish. Note: This is NOT honored by other network related commands, eg dist-tags, owner, etc.
  • --otp β€” Default: null. Type: null or String. This is a one-time password from a two-factor authenticator. It's needed when publishing or changing package permissions with npm access. If not set, and a registry response fails with a challenge for a one-time password, npm will prompt on the command line for one.
  • --workspace, -w β€” Default: (blank). Type: String (can be set multiple times). Enable running a command in the context of the configured workspaces of the current project while filtering by running only the workspaces defined by this configuration option. Valid values for the workspace config are either:
    • Workspace names
    • Path to a workspace directory
    • Path to a parent workspace directory (will result in selecting all workspaces within that folder)

When set for the npm init command, this may be set to the folder of a workspace which does not yet exist, to create the folder and set it up as a brand new workspace within the project.

  • --workspaces β€” Default: null. Type: null or Boolean. Set to true to run the command in the context of all configured workspaces. Explicitly setting this to false will cause commands like install to ignore workspaces altogether. When not set explicitly:
    • Commands that operate on the node_modules tree (install, update, etc.) will link workspaces into the node_modules folder.
    • Commands that do other things (test, exec, publish, etc.) will operate on the root project, unless one or more workspaces are specified in the workspace config.
  • --include-workspace-root β€” Default: false. Type: Boolean. Include the workspace root when workspaces are enabled for a command. When false, specifying individual workspaces via the workspace config, or all workspaces via the workspaces flag, will cause npm to operate only on the specified workspaces, and not on the root project.
  • --provenance β€” Default: false. Type: Boolean. When publishing from a supported cloud CI/CD system, the package will be publicly linked to where it was built and published from. When the provenance-file config is set, it takes precedence and automatic provenance generation (including via trusted publishing/OIDC) is skipped.

πŸ’… npm stage list πŸ’…

List all staged package versions.

✨ Synopsis ✨

npm stage list [<package-spec>]

🌈 Flags 🌈

  • --json β€” Default: false. Type: Boolean. Whether or not to output JSON data, rather than the normal output.
    • In npm pkg set it enables parsing set values with JSON.parse() before saving them to your package.json. Not supported by all npm commands.
  • --registry β€” Default: "https://registry.npmjs.org/". Type: URL. The base URL of the npm registry.

πŸ’… npm stage view πŸ’…

View details of a specific staged package.

✨ Synopsis ✨

npm stage view <stage-id>

πŸŽ€ Flags

okay bestie these are the flags hanging out on the main npm stage vibe β€” here's the whole lineup, no cap:

  • --json β€” default is false, type is Boolean ✨ This one decides whether you get JSON data out instead of the normal output. And like, extra detail: in npm pkg set it turns on parsing set values with JSON.parse() before saving them into your package.json. Heads up though β€” not all npm commands support this one, so don't come for me if it ghosts you.
  • --registry β€” default is "https://registry.npmjs.org/", type is URL 🌈 This is literally the base URL of the npm registry. That's it. That's the whole thing.

πŸ‘‘ npm stage approve

Approve a staged package and publish it to the npm registry β€” the ultimate "yes bestie, go off" moment πŸ’…

Synopsis

npm stage approve <stage-id>

Flags

  • --otp β€” default is null, type is null or String πŸ”₯ This is a one-time password from a two-factor authenticator. You need it when publishing or changing package permissions with npm access. If it's not set and the registry throws back a challenge asking for a one-time password, npm will just prompt you on the command line for one β€” so no stress, it's got you.
  • --registry β€” default is "https://registry.npmjs.org/", type is URL 🌸 The base URL of the npm registry. Iconic, we know her.

πŸ’€ npm stage reject

Reject a staged package, and it gets removed from the registry. it's giving "we're not doing this today" πŸ™ˆ

Synopsis

npm stage reject <stage-id>

Flags

  • --otp β€” default is null, type is null or String πŸ¦‹ One-time password from a two-factor authenticator. Needed when publishing or changing package permissions with npm access. If it's not set and a registry response fails with a challenge for a one-time password, npm prompts you on the command line for one. Same energy as approve, fr.
  • --registry β€” default is "https://registry.npmjs.org/", type is URL πŸ“ Base URL of the npm registry. Still her.

πŸ” npm stage download

Download the tarball of a staged package so you can inspect it β€” literally the "let me look at it before I commit" main character move πŸ‘€

Synopsis

npm stage download <stage-id>

Flags

  • --json β€” default is false, type is Boolean ⭐ Whether or not to output JSON data rather than the normal output. Bonus lore: in npm pkg set it enables parsing set values with JSON.parse() before saving them to your package.json. Also worth knowing β€” it's not supported by all npm commands.
  • --registry β€” default is "https://registry.npmjs.org/", type is URL πŸ’œ The base URL of the npm registry. Yes, again. She's everywhere.

🌈 See Also

  • npm help publish
  • npm help unpublish
  • npm help trust

and that's the whole page, bestie β€” you ate that πŸ’…βœ¨ go forth and stage responsibly 🫢

this was NPM@12.2.1, dated October 2026, page NPM-STAGE(1) β€” mwah, ilysm, bye πŸŽ€

πŸ“¦ where this page comes from