Skip to content

npm Repositories

View as Markdown

Use the npm CLI with a CloudRepo npm repository: publish your packages to it and install them from it.

1. Put the registry and the credential in ~/.npmrc. npm replaces ${CLOUDREPO_TOKEN} with the environment variable of that name, so the file holds no token and can be copied or committed:

~/.npmrc
registry=https://your-org.mycloudrepo.io/repositories/your-repo/
//your-org.mycloudrepo.io/repositories/your-repo/:_authToken=${CLOUDREPO_TOKEN}

Keep the trailing / on both lines, and keep the second line identical to the registry URL without https:. npm sends the token only to the registry that prefix names: if the two differ, even by the slash, npm sends no token at all. npm sends the token on every request to that registry, installs included, so no always-auth setting is needed (npm 11 warns that always-auth is an unknown option).

2. Check the connection.

Terminal
npm whoami
npm ping

Expected: npm whoami prints your email address, and npm ping ends with PONG.

3. Publish. Run this in the directory of your package:

Terminal
npm publish

A package may be scoped (@scope/name) or unscoped.

4. Install it from another project. Because the registry is in ~/.npmrc, any project on your machine reads from CloudRepo:

Terminal
mkdir consumer && cd consumer
npm init -y
npm install docs-npm

Alternative: sign in with npm login. For a person at a keyboard, npm login opens the admin portal in your browser. Set the registry first, so npm knows which CloudRepo registry to sign in to:

Terminal
npm config set registry https://your-org.mycloudrepo.io/repositories/your-repo/
Terminal
npm login

npm opens https://admin.cloudrepo.io/npm-login?session=<id>. Sign in with your CloudRepo email and password (or reuse a portal session), authorize on the Authorize npm CLI page, and npm writes the token to ~/.npmrc for you. That token is bound to the repository you ran npm login against, and only if it is a local npm repository: a proxy npm repository refuses it with 403 (npm_token_not_supported_on_proxy), even though the login itself succeeds. Use a token from Repository Tokens there. The token is read-only unless you choose Read-write on that page and your user has write access, so npm publish answers 403 with a read-only one.

If the terminal never returns after you authorize, the session expired: it lasts five minutes. Run npm login again.

Alternative: Basic authentication. Some older CI tooling needs _auth. Its value is the base64 of your email address, a colon and the token. Build it from the variable:

Terminal
printf '%s' "you@example.com:$CLOUDREPO_TOKEN" | base64
~/.npmrc
registry=https://your-org.mycloudrepo.io/repositories/your-repo/
//your-org.mycloudrepo.io/repositories/your-repo/:_auth=BASE64_ENCODED_CREDENTIALS

Prefer _authToken above: it needs no encoding step.

The legacy npm login --auth-type=legacy flag is no longer supported. CloudRepo answers it with 410 Gone and points you at the web login or a repository token. Modern npm rejects an email address as a username, and CloudRepo’s users are identified by email address.

To install private packages from CloudRepo and everything else from the default registry, route a scope to CloudRepo in .npmrc:

.npmrc
@yourorg:registry=https://your-org.mycloudrepo.io/repositories/your-repo/
//your-org.mycloudrepo.io/repositories/your-repo/:_authToken=${CLOUDREPO_TOKEN}

This sends @yourorg/* packages to CloudRepo and every other package to npm’s default registry. CloudRepo accepts both scoped (@scope/name) and unscoped packages.

To publish a scoped package, create it with the scope and publish as usual:

Terminal
npm init --scope=@yourorg -y
npm publish

If npm install @scope/package answers 404, npm is asking the default registry for that scope. Add the scope line above.

CloudRepo accepts an npm publish of up to 210 MiB (220,200,960 bytes), which holds a tarball of about 155 MiB (base64 encoding adds about a third). A larger publish is refused with 413. If you need to publish larger packages, split them into several.

Remove one version, or every version of a package. CloudRepo lets a write-capable credential unpublish any version at any time, and Overwrite Protection does not block it.

Terminal
npm unpublish my-package@1.0.0
npm unpublish my-package --force

For scripts, the registry’s own paths remove a package too. Send the same credential as npm: put it in ~/.netrc and ask curl to read it (see Maven Repositories for the file). First read the current revision from the package metadata, then delete with it.

Terminal
# Remove one version: read the current revision, then delete the tarball with it
REVISION=$(curl --netrc --silent \
https://your-org.mycloudrepo.io/repositories/your-repo/my-package/ \
| jq -r '._rev')
curl --netrc --request DELETE \
"https://your-org.mycloudrepo.io/repositories/your-repo/my-package/-/my-package-1.0.0.tgz/-rev/$REVISION"
Terminal
# Remove the whole package (all versions)
REVISION=$(curl --netrc --silent \
https://your-org.mycloudrepo.io/repositories/your-repo/my-package/ \
| jq -r '._rev')
curl --netrc --request DELETE \
"https://your-org.mycloudrepo.io/repositories/your-repo/my-package/-rev/$REVISION"

npm reads two kinds of CloudRepo token. The one the npm login web flow writes into your .npmrc has the npm format (crn_v1_) and works on local npm repositories only. One you create under Repository Tokens (crp_v1_) works on every repository type it reaches. Each is revocable from the admin portal without affecting your login or your other credentials. See Repository Tokens: Create One and Authenticate.

npm token create is not supported against CloudRepo: it answers 410 Gone and points you at the portal. npm token list shows the tokens npm login created for you, and npm token revoke <id> revokes one. A token from Repository Tokens appears and is revoked only in the admin portal.

After npm login, npm stores the token in your .npmrc:

~/.npmrc
//your-org.mycloudrepo.io/repositories/your-repo/:_authToken=crn_v1_...

npm sends it as a Bearer header on every later request to the registry.

Keep the token in your CI platform’s secret store, expose it as the environment variable CLOUDREPO_TOKEN, and let .npmrc name the variable, as in the first step. Then the build runs plain npm:

Terminal
npm install
npm publish

To write the .npmrc at build time instead:

Terminal
echo '//your-org.mycloudrepo.io/repositories/your-repo/:_authToken=${CLOUDREPO_TOKEN}' >> .npmrc

The single quotes matter: they write the text ${CLOUDREPO_TOKEN} into the file, and npm replaces it with the variable’s value when it runs, so the file never holds the token.

npm sends _authToken as a Bearer token. A token that is mistyped, expired, revoked or from another organization answers 404 Not Found, not 401, so npm reports the package as not found. If npm reports 404 for a package you know exists, check the token first. Check, in order:

  • The //your-org.mycloudrepo.io/repositories/your-repo/: prefix on the _authToken line matches your registry= line exactly, without https: and with the trailing slash.
  • The token reaches this repository. A token from npm login (crn_v1_) works only on the local npm repository you logged in to, and a proxy npm repository refuses it with 403: use a token from Repository Tokens for a proxy repository.
  • If npm publish answers 403: a token from npm login is read-only unless you chose Read-write when you authorized it and your user has write access.
  • The token has not expired or been revoked: check the Repository Tokens page.

When the registry URL or the token prefix lacks the trailing slash, they no longer match, so npm sends no token and commands fail as if you had not signed in. End both with /:

Terminal
# Right
npm config set registry https://your-org.mycloudrepo.io/repositories/your-repo/
# Wrong: the prefix on the token line no longer matches
npm config set registry https://your-org.mycloudrepo.io/repositories/your-repo

npm publish fails with “Version already exists”

Section titled “npm publish fails with “Version already exists””

npm publish answers 409 Conflict when a package with that version already exists and Overwrite Protection is on, which is the default on every npm repository. npm prints CloudRepo’s explanation: Version already exists. Overwrites are disabled for this repository.

Increment the version in package.json before publishing. If the repository is meant to accept republished versions, turn Overwrite Protection off in its settings instead. npm has no mutable-version convention, so there is no equivalent of Maven’s -SNAPSHOT escape hatch here: no version is exempt.