# Install npm packages from CloudRepo

> Point npm at a CloudRepo repository with a repository token, install private packages, keep public ones coming from npm, and fix a 401, 403 or 404.

npm reads CloudRepo like any other npm registry: point npm at the repository, give it the token, and install. This page is for the person whose project installs from a repository. To put packages there, see [Publish npm packages](/docs/formats/npm.html).

You need an npm repository and a repository token that reaches it. If you have neither yet: [create a repository](/docs/manage/repositories.html#creating-a-repository) and [create a token](/docs/authenticate/repository-tokens.html). A token that is **Read only** is enough to install.

## Point npm at the repository

Put this in the `.npmrc` beside your `package.json`. It sends the packages of your own scope to CloudRepo and everything else to the public npm registry, so no public package has to be in your repository.

`.npmrc`

```ini
@acme:registry=https://your-org.mycloudrepo.io/repositories/your-repo/
//your-org.mycloudrepo.io/repositories/your-repo/:_authToken=${CLOUDREPO_TOKEN}
```

- Replace `@acme` with the scope of your private packages.
- npm replaces `${CLOUDREPO_TOKEN}` with the environment variable of that name, so the file can be committed without the token in it.
- 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 line names.
- npm sends the token alone, as `_authToken`. There is no username.

The repository URL is `https://<organization>.mycloudrepo.io/repositories/<repository>/`: your organization’s name, then the repository’s name as the admin portal shows it.

Check that CloudRepo accepts the token:

**Terminal**

```bash
npm whoami --registry=https://your-org.mycloudrepo.io/repositories/your-repo/
```

Expected: npm prints the email address of the account that created the token. A token that is mistyped, expired or revoked fails here (see [When npm answers 401, 403 or 404](#when-npm-answers-401-403-or-404)).

## Install a package

**Terminal**

```bash
npm install @acme/my-package
```

Expected: npm adds the package to `node_modules` and to `package.json`.

A package without a scope can live in a CloudRepo repository too. npm then needs the repository as its registry for everything, so use `registry=` in place of the `@acme:registry=` line:

`.npmrc`

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

A hosted repository holds only what was published to it, so with `registry=` a public package it does not hold is not found. To install public packages through CloudRepo as well, create an npm [proxy repository](/docs/consume/proxy-repositories.html) and use that as the registry.

## When npm answers 401, 403 or 404

npm sends `_authToken` as a Bearer token, and a Bearer token that is mistyped, expired, revoked or from another organization answers `404 Not Found`, not `401`. npm then reports the package as not found. If npm reports `404` for a package you know exists, check the token first, and then whether the token reaches the repository (a proxy repository it does not reach also answers `404`).

Check these in order:

- **The token line.** Its `//your-org.mycloudrepo.io/repositories/your-repo/:` prefix must match the registry URL exactly, without `https:` and with the trailing slash.
- **The token.** Paste it whole, starting at `crp_v1_`, and check on the **Repository Tokens** page that it has not expired or been revoked.
- **The repository.** A token reaches only the repositories ticked when it was created. A hosted repository it does not reach answers `403 Forbidden`, and a proxy repository it does not reach answers `404 Not Found`, not `403`: if you installed through a proxy and got a `404` with a good token, check that the token includes the proxy.
- **The scope.** If `npm install @acme/my-package` answers `404` and the token is good, npm is looking at the public registry: the `@acme:registry=` line is missing, or names another scope.
- **An `npm login` token.** A token from `npm login` (`crn_v1_`) works only on the local npm repository you logged in to. A proxy npm repository refuses it with `403`. Use a token from **Repository Tokens** there.

More: [Repository tokens](/docs/authenticate/repository-tokens.html), for every client’s credential and the `npm login` browser flow; [Proxy repositories](/docs/consume/proxy-repositories.html); [npm repositories](/docs/formats/npm.html), for publishing, size limits and unpublishing.

---

The page: https://www.cloudrepo.io/docs/consume/npm.html
