Install NPM Dependencies from Multiple Registries

At work I deal with an internal npm registry for shared packages. Getting those to install alongside public packages like react wasn’t immediately obvious, since npm doesn’t just figure it out on its own. Here’s how to configure it properly using .npmrc.
TL;DR: To use a private npm registry in your project, add the following lines to your .npmrc file:
@{scope}:registry={your_private_registry}//{your_private_registry}/:_authToken={YOUR_AUTH_TOKEN_HERE}By default, npm install pulls all dependencies listed in your package.json from the public npm registry. However, many enterprise or internal projects rely on packages hosted in private npm registries.
You can configure npm to install public packages from the default registry and private packages from your own private registry by scoping them and updating your .npmrc accordingly.
Example
If your package.json includes:
"dependencies": { "@rayhannr/validator": "3.1.0", "react": "18.3.1"}And your .npmrc looks like this:
@rayhannr:registry=https://registry.rayhannr.org//registry.rayhannr.org/:_authToken={YOUR_AUTH_TOKEN_HERE}Then:
reactwill be downloaded from the publicnpmregistry@rayhannr/validatorwill come from@rayhannrprivate registry
When your private packages aren’t scoped
If your private package names aren’t prefixed with a scope (e.g., @rayhannr), update your .npmrc to:
registry=https://registry.rayhannr.org//registry.rayhannr.org/:_authToken={YOUR_AUTH_TOKEN_HERE}This tells npm to fetch all packages from your private registry. For public packages like react to still resolve, your private registry needs to be configured to proxy requests it can’t fulfill to registry.npmjs.org. If it isn’t set up that way, npm install will fail for anything not hosted on your registry.
Auth tokens
Private registries require an access token in your .npmrc to authenticate.
If you’re using Sonatype Nexus Repository Manager, the token format is slightly different: it expects a Base64-encoded string of username:password:
echo -n "admin:admin123" | base64Which outputs:
YWRtaW46YWRtaW4xMjM=A few things worth noting
Don’t commit real tokens. It’s common to check .npmrc into version control so the registry URL is shared across the team, but the auth token should never be in there as a literal value. Use an environment variable reference instead:
@rayhannr:registry=https://registry.rayhannr.org//registry.rayhannr.org/:_authToken=${NPM_TOKEN}Each developer sets NPM_TOKEN locally, and in CI it gets injected as a secret.
In GitHub Actions, you can pass it in via your workflow:
- name: Install dependencies run: npm install env: NPM_TOKEN: ${{ secrets.NPM_TOKEN }}npm will substitute ${NPM_TOKEN} from the environment when it reads your .npmrc.
If you get a 401, the token is either wrong or expired. Double-check the value and that it has read access to the registry. For Nexus, also make sure the token is re-encoded if the password changed.

