Safeguard
Developer Tools•

Which npmrc file wins, and where should registry tokens go?

npm reads project, user, global and built-in npmrc files plus env vars and flags. Which wins, how auth keys are scoped to a registry, where tokens belong.

Safeguard Security Team
4 min read

npm merges settings from command line flags, environment variables and four npmrc files: project, user, global and built-in. Higher sources override lower ones. Auth tokens must be scoped to a registry host in the key name, and the safest place for the value is an environment variable referenced from the file.

The sources, in priority order

The npm docs list the sources by priority. In the config source, the precedence for conflicts is: command line, environment, project, user, global. The built-in file sits at the bottom and is mostly for people who package npm itself.

SourceLocationNotes
Command lineflagsHighest priority
Environmentvariables beginning with npm_config_Underscores replace dashes
Project.npmrc next to package.jsonOnly applies to the project root
User.npmrc in the home folderPer person
Globaletc/npmrc under the prefixPer machine
Built-innpmrc inside npmUnchangeable by users

Two details from the docs: a project .npmrc has no effect when your package is published, so a module cannot force settings on consumers, and it is not read in global mode such as installing with the global flag.

Why tokens are scoped to a host

The auth keys, including _authToken and _auth, must be scoped to a registry. The docs state this ensures npm will never send credentials to the wrong host. The prefix is a URI fragment:

; good
@myorg:registry=https://registry.example.org/myorg
//registry.npmjs.org/:_authToken=${NPM_TOKEN}

; bad, unscoped
_authToken=MYTOKEN

A scope can cover a whole host or a path on that host, so two scopes on one host can use different tokens.

Keep the secret out of the file

The docs say environment variables can be substituted with ${VARIABLE_NAME} in npmrc files. If the variable is not defined, the text is left unreplaced, and adding a question mark after the name makes it evaluate to an empty string. Use that so the committed project file contains a reference, not a token. Put the real value in your CI secret store.

Habits that follow:

  1. Commit a project .npmrc with registries and scopes, never with a literal token.
  2. Keep personal tokens in the user file, outside any repository.
  3. Use the narrowest token that works, and rotate it. See rotating a CI registry token.
  4. Check that .npmrc is not copied into container images or build contexts.

Surprising precedence cases

A flag beats the project file, so a pipeline step with a registry flag overrides your committed policy. A user-level setting can also differ from CI, which is a common reason an install works on a laptop and fails in a pipeline. When debugging, run npm config list to see which source supplied each value.

Unknown keys

Starting in npm v11.2.0, npm warns when it finds unsupported keys in .npmrc, and a future major version may stop accepting them. For tool-specific settings the docs recommend environment variables or the config field in package.json.

Where Safeguard fits

Config controls what npm does. Safeguard's dependency scanning and policies check what your lockfiles resolve afterward, which is useful when a precedence surprise sends an install to the wrong place. A free scan is at https://gold.safeguard.sh/scan.

Quick check

Does a project .npmrc apply to people who install my package?

No. The docs say it has no effect when your module is published, so you cannot force settings on consumers.

Why must tokens be scoped to a registry?

So npm never sends credentials to the wrong host. Unscoped keys are treated as bad config in the npm docs.

Sources

Last reviewed: 19 October 2026.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.