# npm dependencies vs devDependencies vs peerDependencies

> Understand the difference between dependencies, devDependencies, peerDependencies, and optionalDependencies in an npm package.json project file

**URL:** https://sentry.io/answers/npm-difference-between-dependencies/

---

## The Problem

A `package.json` file often contains different types of dependencies. For example:

```json
{
  "name": "my-project",
  "dependencies": {
    "foo": "^1.0.0"
  },
  "devDependencies": {
    "bar": "^1.2.1"
  },
  "peerDependencies": {
    "baz": "^2.5.4"
  },
  "optionalDependencies": {
    "boo": "^3.1.0"
  }
}
```

What is the difference between these dependencies?

## The Solution

Dependencies are the packages that your project depends on. But dependencies may serve various purposes. For example, you may need a dependency to build your project, another to run it, another to test it, and so on.

For this reason, in a `package.json` file, different types of dependencies are listed in different objects. Each object stands for a different type of dependency.

### The `dependencies` Object

The `dependencies` object specifies the packages that you need to run your code. For example React, Vue, Firebase, etc.

When you run `npm install some-package`, npm installs the package and adds it to the `dependencies` object in the `package.json` file.

If you are working on someone else's code (let's say you cloned a repository from GitHub), and you run `npm install` from the root folder of the project, npm will install all the dependencies that are listed in the `dependencies` object.

### The `devDependencies` Object

The `devDependencies` object maps the packages that you will only need during the development of your project. You don't need them to run your code in production. For example, a testing framework like Jest, or other utilities like ESLint.

When you run `npm install some-package --save-dev`, npm installs the package and adds it to the `devDependencies` object in the `package.json` file.

If you run `npm install` on a cloned repository, npm assumes that you are developing the project. That's why it will also install all the dependencies listed in the `devDependencies` object.

If you do not want to install `devDependencies` you can use the `--omit=dev` flag, like so:

`npm install --omit=dev`

The package manager will only install the dependencies listed in the `dependencies` object.

### The `peerDependencies` Object

The `peerDependencies` object is a little different to the other dependencies.

For one, you only need `peerDependencies` if you are developing your own plugin.

Let's say you created a plugin called `'choco-chip-cookies'`. Your module is relying on `'peanut-butter'`, and your plugin is only compatible with v1 of `'peanut-butter'`.

```json
{
  "name": "choco-chip-cookies",
  "version": "1.3.5",
  "peerDependencies": {
    "peanut-butter": "1.x"
  }
}
```

Adding `peanut-butter` to the `peerDependencies` object ensures that your package `choco-chip-cookies` can only be installed along with the major version '1' of the host package `peanut-butter`.

According to [the official npm documentation](https://docs.npmjs.com/cli/v8/configuring-npm/package-json#dependencies):

> In npm versions 3 through 6, `peerDependencies` were not automatically installed, and would raise a warning if an invalid version of the peer dependency was found in the tree. As of npm v7, `peerDependencies` _are_ installed by default.

You can add dependencies to the `peerDependencies` object by manually modifying the package.json file.

### The `optionalDependencies` Object

As the name implies, `optionalDependencies` are optional.

Let's say you have a dependency that may be used, but you would like the package manager to proceed if it cannot be found or fails to install. In that case, you can add those dependencies in the `optionalDependencies` object.

A good use case for `optionalDependencies` is if you have a dependency that won’t necessarily work on every machine. But you should have a fallback plan in case the installation fails. An example for `optionalDependencies` can be services like Watchman.

You can add dependencies to the `optionalDependencies` object by manually modifying the `package.json` file.

---

*Source: [sentry.io/answers/npm-difference-between-dependencies/](https://sentry.io/answers/npm-difference-between-dependencies/)*
