Unpublishing a Package Within npm Policy
npm unpublish removes versions from the registry — but on the public npm registry it is deliberately restricted. Since the 2016 left-pad incident, when removing one small package broke thousands of builds, npm allows unpublishing only when it is unlikely to hurt anyone: shortly after publishing, or for packages nobody depends on. Knowing the rules saves time when you publish something by mistake — often under pressure, minutes after the mistake — and knowing the alternatives matters more, because most situations that feel like they need an unpublish are better served by deprecation. This guide explains the policy, the commands and errors, what happens to the name afterwards, and what to do with leaked secrets.
The policy in brief
On the public registry, you can unpublish:
- Within 72 hours of publishing a version, provided no other public package depends on it.
- After 72 hours, only if all of these are true: no other public packages depend on it, it had fewer than 300 downloads in the last week, and it has a single owner or maintainer.
Additional rules:
- Version numbers are never reusable. Once
1.4.0has been published, that version can never be published again, even after unpublishing. - Unpublishing every version removes the package, and the name cannot be republished for 24 hours.
- Removing the last version is the same as removing the whole package.
Policies can change, so check npm's current unpublish policy before relying on the details. The wider lifecycle is covered in Package Deprecation and Lifecycle.
Commands and errors
# Remove a single version
npm unpublish @acme/sdk@2.4.0
# Remove the entire package (all versions) — requires --force
npm unpublish @acme/sdk --force
# Check what remains
npm view @acme/sdk versions --json
Refusals look like this:
npm error code E405
npm error 405 Method Not Allowed - PUT https://registry.npmjs.org/@acme%2fsdk/-rev/... - You can no longer unpublish this package. Failed criteria:
npm error has dependent packages in the registry
npm error Please deprecate the package instead
Unpublishing is a write that requires publish rights, and with 2FA required, a one-time password.
When unpublishing is the right call
Legitimate reasons, ideally caught within the 72-hour window:
- An accidental publish — a private package published publicly, a test package published to the real name, a version published from the wrong branch.
- Content that must not be distributed — files included by mistake, such as internal documentation or customer data.
- A new package with no users that you have decided not to pursue.
For everything else — a buggy release, a vulnerable version, an unwanted old line — deprecate and publish a fix, as described in Deprecating npm Package Versions. Unpublishing a version people use breaks their installs, which is exactly what the policy exists to prevent.
The 72-hour window in practice
The window rewards catching mistakes quickly, so build the habit of checking every release right after it lands. A post-publish step in the release job can do most of it automatically:
A useful post-publish check downloads the just-published tarball with npm pack <name>@<version>, lists its files, compares them with the expected list, installs it into a scratch project and imports it. If anything is wrong, the job fails loudly while unpublishing is still an option. For monorepos, run the check for every package the release published; a mistake in one package of a large release is easy to miss in the log.
Dependents are the condition most likely to block you even inside the window. In a monorepo, a release that publishes @acme/core@2.4.0 and @acme/react@2.4.0 together makes react a dependent of core immediately, so core@2.4.0 cannot be unpublished alone. Unpublish the dependents first (they have no dependents of their own, if nothing else uses them), then the dependency — or, more practically, deprecate the whole set and publish a fixed release.
Squatting and name protection after a full unpublish
If you remove an unscoped package completely because it was published by mistake, decide deliberately whether you want to keep the name. Publishing a placeholder after the 24-hour block — a minimal package with a README explaining that the name is reserved — prevents others from claiming it, which matters when the name resembles your internal package names or your brand.
Leaked secrets: unpublish is not the fix
If a published tarball contained a secret — an .env file, a token in a config, a private key — treat the secret as compromised the moment it was published. Public registry content is mirrored and scanned by third parties within minutes, so removing the version does not remove copies that already exist.
- Rotate or revoke the secret immediately. This is the only step that actually protects you.
- Unpublish the version if the policy allows, to limit further distribution; otherwise deprecate it and contact npm support, which can act on security and legal issues outside the normal policy.
- Publish a clean version so users who installed the bad one can move on.
- Fix the cause — usually a missing
filesallowlist — as covered in Choosing Between the files Field and .npmignore.
What happens to the name
After a full unpublish, the name is blocked for 24 hours, then becomes available again. Scoped names can only be republished by the scope's owner, so an unpublished @acme/sdk cannot be taken by someone else. Unscoped names can be claimed by anyone after the 24-hour period, which creates a squatting risk: if the package had users (or dependents in your own organisation), someone else could publish malicious code under the old name. Prefer deprecation for any unscoped package that had real users, or keep the name by publishing a placeholder version after the block ends. Name reuse is one of the paths described in Preventing Dependency Confusion Attacks.
Worked example: a private package published publicly
A developer runs npm publish in an internal package whose publishConfig.registry was missing, and @acme/billing-internal@1.0.0 lands on the public registry. The package is scoped to the company's organisation, so nobody else can publish under that name, but its code is now public. Thirty minutes later the team runs npm unpublish @acme/billing-internal --force — allowed because it is within 72 hours and nothing depends on it — rotates an API key that appeared in a test fixture, adds publishConfig.registry and "private": false checks to the release checklist, and sets up a CI guard that refuses to publish any package without an explicit publishConfig.registry.
Private registries
Most private registries let administrators delete versions freely. The same caution applies: deleting a version that other teams' lockfiles reference breaks their builds. Prefer deprecation internally too, and reserve deletion for mistakes and leaked content. Where a private registry proxies the public one, remember that an unpublished public version may still be served from the proxy's cache until an administrator removes it there as well.
Prevention and guardrails
- Mark internal packages
"private": trueunless they are meant to be published. - Set
publishConfig.registryandaccessexplicitly on every published package. - Dry-run every publish to see contents, registry and access before uploading, as in Dry-Running a Publish Before Release.
- Default to deprecation for anything that has users.
Frequently Asked Questions
Can I republish the same version number after unpublishing? No. A version number can be used only once, forever. Publish a new version instead.
Why does npm say my package has dependents when I do not know any?
Another public package lists yours in its dependencies. npm view and the registry page show dependents; those packages would break if yours disappeared.
Can npm support remove a package that does not meet the policy? For security, legal or abuse issues, npm support can intervene. For ordinary regret about a release, the answer is deprecation.
Does unpublishing remove the package from mirrors and caches? No. Public mirrors, security scanners and proxy registries may already hold copies. Unpublishing stops new downloads from the npm registry; it does not recall existing copies, which is why leaked secrets must always be rotated.
Can an organisation owner unpublish a package another member published? Anyone with publish rights on the package can unpublish within the policy. For organisation packages, that usually means members of teams with read-write access; restrict those teams to people who should be able to take such an irreversible step.
Related
- Package Deprecation and Lifecycle covers lifecycle actions and their trade-offs.
- Deprecating npm Package Versions is the default alternative to unpublishing.
- Fixing npm 'Cannot Publish Over Previously Published Version' explains why version numbers cannot be reused.
- Responding to a Compromised Dependency covers incidents where removal and rotation both matter.