Publish private packages
Pier accepts the standard npm publish flow for both scoped (@org/name) and unscoped (name) packages. The protocol is the CouchDB-style PUT with _attachments — same wire format every npm CLI sends to npmjs.org.
Publish a scoped package
Section titled “Publish a scoped package”# package.json{ "name": "@your-org/my-lib", "version": "1.0.0", "publishConfig": { "registry": "https://YOUR-PIER-HOST/registry/npm/" }}npm publish# published @your-org/[email protected]The publishConfig is the standard way to pin one package’s publish target without changing the global registry. If you don’t set it, npm uses the registry from your .npmrc.
Publish an unscoped package
Section titled “Publish an unscoped package”Same flow, no @scope/:
# package.json{ "name": "my-internal-lib", "version": "1.0.0"}npm publish --registry=https://YOUR-PIER-HOST/registry/npm/Unscoped private packages collide with the public namespace if you also have upstream proxy on. If
my-internal-libalready exists onnpmjs.org, Pier still accepts your publish, and your private version shadows the proxy entry. We recommend scoped names (@your-org/…) for clarity.
Integrity verification
Section titled “Integrity verification”If your CLI sends dist.integrity in the publish body, Pier compares it against the sha512 of the uploaded tarball and rejects mismatches with a 400. If not sent, Pier computes the integrity from the bytes and stores it. Either way every stored tarball has a verified sha512.
Dist-tags
Section titled “Dist-tags”npm dist-tag ls @your-org/my-lib# latest: 1.2.0# beta: 1.2.0npm dist-tag rm @your-org/my-lib betalatest is the only required tag. You can have any number of named tags pointing at any version.
Deprecate a version
Section titled “Deprecate a version”The deprecation message lands in npm_versions.manifest_json.deprecated, surfaces on the package detail page, and shows up in clients with npm warn on install. To un-deprecate, pass an empty message:
Unpublish
Section titled “Unpublish”# single version
# whole packagenpm unpublish @your-org/my-lib --forcePier deletes the version row (or the package row + all versions for a whole-package unpublish), removes the tarball from disk, and writes a tombstone so re-publishing the same name+version is rejected — matching npm policy.
Unpublish is the only destructive operation reachable via CLI. Be careful — there’s no undo.
Authentication for publish
Section titled “Authentication for publish”npm publish sends the bearer token from .npmrc:
//YOUR-PIER-HOST/registry/npm/:_authToken=pier_npm_…Or use npm login --auth-type=web to do the OAuth-style browser flow (with 2FA enforcement):
npm login --auth-type=web --registry=https://YOUR-PIER-HOST/registry/npm/# Opens the browser → authenticate in Pier panel → token in .npmrcCommon errors
Section titled “Common errors”E409 Conflict— you’re re-publishing a version that already exists. Bump the version inpackage.json. (See Troubleshooting for the full list.)401 Unauthorized— token missing or revoked. Mint a fresh one in Packages → Manage tokens.400 attachment name mismatch— your CLI is sending an unexpected_attachmentskey. Most clients send@scope/name-version.tgz(full) orname-version.tgz(short) — Pier accepts both.
Next steps
Section titled “Next steps”- CI integration — automate publish from your build pipeline.
- Per-client guides — client-specific publish quirks.