To use a private registry for your own packages, add a scope line to .npmrc and a token line scoped to that registry host. npm then sends only packages in that scope to the private registry and sends credentials only to the host they are tied to. Keep real tokens out of committed files.
The two lines
From the npm documentation:
@myscope:registry=https://mycustomregistry.example.org
//mycustomregistry.example.org/:_authToken=${NPM_TOKEN}
The first sends every package under the myscope scope to that registry. Unscoped packages use the default registry, which the npm docs give as https://registry.npmjs.org. The second line attaches a token to that host. Environment variables can be inserted with a dollar sign and braces, so the real secret stays outside the file.
Why the token line has a host prefix
The npmrc page says _auth, _authToken, username and _password must all be scoped to a specific registry. The scoping exists so npm never sends credentials to the wrong host. An unscoped _authToken line is shown there as a bad configuration.
Where the files live
npm reads four files:
- Per project: .npmrc next to package.json
- Per user: ~/.npmrc
- Global: under the npm prefix
- Built in, mainly for distribution maintainers
A setting in the user file overrides the same one in the global file. The project file is not read in global mode, such as an npm install with the global flag.
Practical layout
- Commit a project .npmrc that contains only the scope to registry line and the token line using an environment variable.
- Set that variable in CI from a secrets store, and locally from your shell.
- Never put a literal token in a committed file. If one was committed, rotate it.
- Use a read only token for installs.
Why scopes are the real protection
An unscoped internal package name is vulnerable if anyone can publish that name publicly. A scope pinned to your registry means the name resolves through your registry. Read npm scopes and package name collisions for that side of the story.
Switching registries and lockfiles
The npm docs note that a lock file created with a custom registry keeps installing from that registry. See what happens to the lockfile when you switch registries.
Safeguard dependency and SBOM scanning can list the npm packages in a repository and flag known vulnerabilities. You can try a free scan at gold.safeguard.sh/scan.
Quick check
Can I put the token in the file as plain text?
You can, but you should not commit it. Use an environment variable reference and keep the secret in a store.
Why does the token line start with double slashes and a host?
It ties the credential to that registry so npm does not send it to another host.
Sources
Last reviewed: 19 October 2026.