Configure package.json variables with npmrc

How to keep credentials out of package.json while still wiring scripts: use npm config variables and per-project .npmrc files.

Configure package.json variables with npmrc

With npm and package.json, you can unify script (task) running, which is great for building and deploying. But you can’t stick usernames/passwords in package.json and still call it “private”.

So how do you wire deploy scripts, keep secrets out of Git, and still keep the project runnable? Use npm config variables, backed by a project-local .npmrc.

The idea

One of the most overlooked (but important) aspects of npm is its config system. You can set config at different scopes:

  • Global (applies to all projects)
  • Project via a .npmrc file next to package.json

The project-level .npmrc is the sweet spot: it keeps per-project settings out of your global config and lets you avoid committing secrets.

Example: script reads config, values come from .npmrc

  1. In package.json, reference config via npm_package_config_*:
{
  "name": "my-package",
  "config": {
    "deploy_user": "",
    "deploy_pass": ""
  },
  "scripts": {
    "deploy": "node deploy.js --user=$npm_package_config_deploy_user --pass=$npm_package_config_deploy_pass"
  }
}
  1. Override values in a project-local .npmrc (don’t commit it):
my-package:deploy_user=john
my-package:deploy_pass=REDACTED

That <package>:<variable>=<value> prefix matters: <package> must match your package.json "name".

Practical tip: add .npmrc to your .gitignore (and keep a .npmrc.example if you want to document the expected keys without committing secrets).

Global config

If you want to skip package.json config entirely, you can also use $npm_config_<variable> for values defined in global/project npm config.

Further reading

The Ultimate Guide to Configuring NPM npm config .npmrc