NPM overview
How to configure and use the Node Packages Manager

-
nvm
is the recommended tool for node.js and npm installation and version management :
# install current node lts, make it the default version and install latest npm release
nvm install --lts --default --latest-npm
# print current version plus versions of all programs relevant to npm: node, v8, uv, openssl, etc
npm version --versions
- This creates the
$HOME/.nvm
directory and makes node and npm available globally for the current user.
- The global prefix points to the location of the currently selected node binaries.
- The local prefix points to the closest directory that contains
node_modules
orpackage.json
.
# returns something like /home/user/.nvm/versions/node/v22.14.0
GLOBAL_PREFIX=$(npm config get prefix -g)
# points to the directory of a project managed by npm
LOCAL_PREFIX="/home/user/projects/my_node_project"
- The global prefix is used to resolve paths to a number of directories that
npm
needs to access :
directory | dir | description |
---|---|---|
$GLOBAL_PREFIX/lib/node_modules/npm/bin |
X | Npm executables |
$GLOBAL_PREFIX/lib/node_modules/npm/man |
X | Man pages |
$GLOBAL_PREFIX/lib/node_modules |
X | Globally installed packages |
$HOME/.nvm/.npmrc |
Global config file | |
$HOME/.npmrc |
User-specific config file | |
$LOCAL_PREFIX/node_modules |
X | Project-specific packages |
$LOCAL_PREFIX/.npmrc |
Project-specific config file |
Note : Any package present in package.json
WILL be installed locally, regardless of it already being installed globally.
- The precedence of configuration values when executing a command with npm is as follows :
- Project-specific config file
- User-specific config file
- Global config file
- Npm internal default values
-
npm config list -l
lists all available configuration options. - Global options can be overriden using user or project specific
.npmrc
, for instance :
; $HOME/.npmrc
; overrides default parameters
color=true
description=true
location=user
shell=/bin/bash
script-shell=/bin/bash
searchlimit=50
update-notifier=true
userconfig=~/.npmrc
viewer=man
; custom values for package.json init
tag=latest
init-author-email=someone@gmail.com
init-author-name=someone
init-author-url=https://github.com/someone
init-license=MIT
init-version=1.0.0
; registry and auth token for default scope
//registry.npmjs.org/:_authToken=npm_XXXXXXXXXXXXXXXXXXXX
@someone:registry=https://registry.npmjs.org/
- When installing packages locally, npm first tries to find an appropriate local prefix.
- That way,
npm install foo@1.2.3
installs to the sensible root of the package even if the command is run from another directory :- Starting at
pwd
, npm walks up the directory tree until it finds eitherpackage.json
ornode_modules
. - Once found, the directory is treated as the "current directory" for the purpose of running npm commands.
- This behavior is similar to git's
.git
directory seeking logic when running git commands from a subdirectory. - If neither
package.json
nornode_modules
are found, then the current directory is used. - In extreme cases, the configuration parameter values can be overriden using
--param
:
- Starting at
# use -- to stop reading CLI configuration flags and resume reading arguments
npm "$command" --param1 value1 --param2 value2 -- argument1
- The default npm public registry is https://registry.npmjs.org (powered by CouchDB).
- Scopes are a way to organize packages when publishing to a registry.
# create a scope to group packages
SCOPE="my-npm-packages"
# show registry configuration (defaults to public registry)
npm config list -l | grep -E "^registry\ =.*$"
# log in to the default registry and links the scope to it
# will save login and authentication token to $HOME/.npmrc
npm login --scope="@$SCOPE"
# show user authentified to configured registry
npm whoami
# log out from default registry, unlink scope, revoke auth token
npm logout --scope="@$SCOPE"
# published package
PACKAGE="my-awesome-package"
# force configuration to global, search configured registry for packages containing "graph"
npm search --location global "graph"
# prints details of package $PACKAGE from configured registry
npm view "$PACKAGE$"
# create a new package in scope $SCOPE
npm init --scope="@$SCOPE"
# lists all dependencies for the current project
npm ls --all
# simulate publishing current package.json to a public package in configured registry
npm publish --dry-run --access public --tag latest .
# unpublishes (removes) release 2.2.3 of $PACKAGE from configured registry
npm unpublish "$PACKAGE@2.2.3"
Note : when publishing, the release / version number of a npm package has to be incremented each time.
# private registry
REGISTRY="https://private.npm-registry.gg/"
# forces the use of $REGISTRY to simulate the installation of $PACKAGE in the current project
npm install --dry-run --registry "$REGISTRY" "$PACKAGE"
# installs $PACKAGE and saves to package.json if current node version matches package.json engine
npm install --save --engine-strict "$PACKAGE"
# installs scoped package $pkg
npm install "@$SCOPE/$PACKAGE"
# prints current/wanted/latest dependencies versions for current project
npm outdated
# updates all dependencies for current project (exercise caution)
npm update --save
# removes $PACKAGE from current project's node_modules and package.json
npm uninstall --save "$PACKAGE"
# locally or remotely runs the command specified in package.json's "bin" field for $PACKAGE
# useful for running built-in CLI commands for modules installed as dependencies
npx "$PACKAGE" "$args" ...