npm Repositories
Use the npm CLI with a CloudRepo npm repository: publish your packages to it and install them from it.
Before you start
Section titled “Before you start”- Node.js and npm. Use npm 10.9.4 or later.
- A CloudRepo npm repository. If you have none, see Creating a Repository.
- A way to authenticate: a repository token (see
Repository Tokens: Create One and Authenticate), or an
account that can sign in to the admin portal to run
npm login. npm sends the token alone, as_authTokenin.npmrc. There is no username.
Connect npm
Section titled “Connect npm”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:
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.
npm whoaminpm pingExpected: npm whoami prints your email address, and npm ping ends with PONG.
3. Publish. Run this in the directory of your package:
npm publishA 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:
mkdir consumer && cd consumernpm init -ynpm install docs-npmAlternative: 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:
npm config set registry https://your-org.mycloudrepo.io/repositories/your-repo/npm loginnpm 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:
printf '%s' "you@example.com:$CLOUDREPO_TOKEN" | base64registry=https://your-org.mycloudrepo.io/repositories/your-repo///your-org.mycloudrepo.io/repositories/your-repo/:_auth=BASE64_ENCODED_CREDENTIALSPrefer _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.
Scoped packages and several registries
Section titled “Scoped packages and several registries”To install private packages from CloudRepo and everything else from the default registry, route a
scope to CloudRepo in .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:
npm init --scope=@yourorg -ynpm publishIf npm install @scope/package answers 404, npm is asking the default registry for that scope.
Add the scope line above.
Package size limit
Section titled “Package size limit”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.
Unpublish a package
Section titled “Unpublish a package”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.
npm unpublish my-package@1.0.0npm unpublish my-package --forceRemove a package through the REST API
Section titled “Remove a package through the REST API”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.
# Remove one version: read the current revision, then delete the tarball with itREVISION=$(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"# 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"Token management
Section titled “Token management”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:
//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:
npm installnpm publishTo write the .npmrc at build time instead:
echo '//your-org.mycloudrepo.io/repositories/your-repo/:_authToken=${CLOUDREPO_TOKEN}' >> .npmrcThe 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.
Troubleshooting
Section titled “Troubleshooting”401, 403 or 404 on npm install
Section titled “401, 403 or 404 on npm install”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_authTokenline matches yourregistry=line exactly, withouthttps: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 with403: use a token from Repository Tokens for a proxy repository. - If
npm publishanswers403: a token fromnpm loginis 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.
The registry URL has no trailing slash
Section titled “The registry URL has no trailing slash”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 /:
# Rightnpm config set registry https://your-org.mycloudrepo.io/repositories/your-repo/
# Wrong: the prefix on the token line no longer matchesnpm config set registry https://your-org.mycloudrepo.io/repositories/your-reponpm 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.
Next steps
Section titled “Next steps”- Repository Management: repository configuration options.
- Continuous Integration and Deployment: CI/CD pipeline integration.