Installation
Install a package
Package installation is probably the most frequent task you'll undertake when using npm.
Initial install
When you initially work on an npm-managed package (for example if you've just git clone
'd the repository to your
local machine) you'll need to install the dependencies it requires to operate.
You can tell you're in this circumstance if the node_modules/
directory is not present, or trying to run the
commands from the scripts
object in the package file results in an error like:
$ npm run something
> [email protected] run something
> script --some args
sh: script: command not found
In this case, you can use the zero-arguments form of npm install
to populate node_modules/
with the dependency tree
defined by package{,-lock}.json
:
$ npm install
# ...
added {x} packages, and audited {y} packages in {z}
For information about the other messages logged out during the installation, see:
Alternatively you can do a Clean install.
Adding new dependencies
Adding new functionality to your package will sometimes require adding new dependencies, too. For example, let's say
you need to manipulate dates and times as part of the behaviour your package offers. You've done some research and
decided date-fns
best meets your needs. You can add it to your package, updating your
package{,-lock}.json
files accordingly, with:
$ npm install date-fns
Categories of dependency
npm maintains various arrays of dependencies for a package, depending on how and when they're intended to be used. You'll most frequently use the following:
- Development (
--save-dev
/-D
flag,devDependencies
array): only used for local development, not required in production - think dev tools like linters (ESLint, ...), test runners (Jest, Mocha, ...), transpilers (Babel, TypeScript, ...) and bundlers (Webpack, ...); and - Production (no flag,
dependencies
array): needed by the application or package at runtime.
Putting dependencies in the correct categories can help with e.g. determining whether known vulnerabilities impact your users or keeping runtime build sizes down, so it's worth considering when you add new dependencies.
Specific versions
If you need to install a specific version of a dependency, you can specify it when running the command. For example, if
you'd like to use Node Fetch, but your package is using CommonJS modules, you need version 2.x (the latest
version,
3.x, uses ES modules):
$ npm install node-fetch@2
Removing redundant dependencies
Remove a package
For example, imagine you've decided to switch from Axios to the built-in fetch
API. You don't want to
leave the unused package in your dependencies, as you'll then have the maintenance burden of keeping it up-to-date and
vulnerability-free. So you remove it from your dependencies:
$ npm uninstall axios
- As you're removing whichever version is installed, there's no need to specify it explicitly.
- This will automatically update your
package{,-lock}.json
files. - If you have a transitive dependency on the package you're removing (i.e. one of your dependencies depends on that
package), it will still be in the dependency tree. You can only remove direct dependencies with
uninstall
.
Clean install
Clean install a project
This command is similar to
npm install
, except it's meant to be used in automated environments such as test platforms, continuous integration, and deployment -- or any situation where you want to make sure you're doing a clean install of your dependencies.
The "clean install" will ensure that the resulting dependency tree exactly matches what's in package-lock.json
. It
bails out with an error if that file's missing, or if the tree described there isn't compatible with the dependencies
listed in package.json
. It also deletes node_modules/
to ensure any unneeded packages or local changes are removed.
You should always use this command in automated build environments. For example, in a GitHub Actions workflow:
- name: 📦 Install dependencies
run: npm ci
or Dockerfile:
COPY ./package*.json ./
RUN npm ci
This gives you clear and early feedback if somebody makes a change that leaves the package and lock files out of sync (or manages to remove one or both of them entirely).