npm packages are no longer guaranteed to become installable the moment npm publish returns. Newly published versions are scanned for malware before general availability. npm says the normal delay is roughly five minutes, although larger packages and busy periods can take 15 minutes or longer.

That is a security improvement, but it changes a common release assumption. A pipeline that publishes a package and immediately installs it in another job may now fail even when the publish was successful.

Quick answer

Treat publication and installability as two different states. After npm publish, poll the registry for the exact version with a bounded timeout, verify its integrity metadata, and only then run downstream smoke tests.

PACKAGE="@acme/payments"
VERSION="2.4.0"

for attempt in {1..30}; do
  if npm view "$PACKAGE@$VERSION" version --json >/dev/null 2>&1; then
    echo "$PACKAGE@$VERSION is available"
    exit 0
  fi
  sleep 20
done

echo "Package was published but did not become available in 10 minutes" >&2
exit 1

The loop is intentionally bounded. An infinite retry hides a blocked release and consumes runner time.

Why old release jobs can fail

Many pipelines perform four steps in one sequence: build, publish, install the new version in an example project, and create a GitHub release. Previously, registry propagation was often quick enough that an immediate install appeared reliable.

With publish-time scanning, npm may accept the upload while holding the package for analysis. npm dist-tag can still work during this period, while operations such as npm deprecate and npm unpublish may remain unavailable until the version is released.

Do not respond by adding a blind five-minute sleep. A fixed delay is slow on fast days and still fails on slow days. Poll the exact version and stop after a documented limit.

Separate upload success from release success

Record three timestamps:

  1. the package upload completed;
  2. the registry returned the exact version;
  3. the downstream install and smoke test passed.

This makes delays visible. If a release is held for review, the team can distinguish it from authentication failure, a missing file, or an incorrect package name.

For public packages, verify through the public registry rather than a local cache:

npm view "@acme/payments@2.4.0" \
  version dist.integrity dist.tarball \
  --registry=https://registry.npmjs.org/

Use npm pack --dry-run before publishing to inspect which files will be uploaded. Malware scanning does not replace your own package-content review.

Make downstream tests reproducible

Once the version appears, install it into a clean temporary project with the lockfile behavior your users rely on. Disable local workspace linking, clear assumptions about a warm cache, and test the actual tarball from the registry.

workdir="$(mktemp -d)"
cd "$workdir"
npm init -y >/dev/null
npm install "@acme/payments@2.4.0" --ignore-scripts
node -e "import('@acme/payments').then(() => console.log('import ok'))"

Whether --ignore-scripts is appropriate depends on the package. The important point is to make script execution an explicit policy instead of an accidental side effect.

Handle a blocked package calmly

A package can be published normally, held for manual review, or blocked. If npm blocks it, the publisher may receive an appeal option. Do not keep changing the version and republishing the same content; that creates noise and may make account review harder.

Preserve the packed tarball, build logs, provenance statement, source commit, and the exact notification. Review unexpected binaries, minified bundles, install scripts, network behavior, and generated files. If the package has legitimate security-sensitive capabilities, npm’s new dual-use declaration may apply.

Update release automation

A reliable pipeline should:

  • publish through trusted publishing or another 2FA-enforced method;
  • save the package tarball and provenance as artifacts;
  • poll the exact version with backoff and a timeout;
  • test from a clean directory after availability;
  • avoid moving a production tag until smoke tests pass;
  • alert a human when review exceeds the normal window.

If consumers use a private proxy, test both npm’s public registry and the proxy. Otherwise a proxy delay can be mistaken for npm scanning.

Primary references

The new delay is not a reason to weaken scanning or rush releases. It is a reason to model package availability as a real state and make the release pipeline wait for evidence rather than time.