arrow_back All posts
Making sense of package dependencies

Making sense of package dependencies

When working with front-end packages, how do you differentiate between direct dependencies, peerDependencies and devDependencies? Let's find out!

Introduction

When developers are tasked with building and maintaining applications, they often have to deal with dependencies. Dependencies refer to the external libraries and packages that a project relies on.

As applications grow and scale, managing these dependencies might be tricky. In this post, we'll try to figure out the main differences between various dependencies fields and how those are supposed to be used.

Understanding dependencies

A visualization of a UI library dependency that is used by multiple applicationsA visualization of a UI library dependency that is used by multiple applications

In simple terms, dependencies are external pieces of code that applications can import and use. These can include libraries, frameworks, and other tools.

Front-end dependencies are managed by package managers like NPM, Yarn or PNPM. They automate the process of installing, updating, and removing packages by using the package.json file to figure out the project's dependencies.

The package.json file includes metadata about the project and specifies the dependencies needed for the project:

{
  "name": "UI Library",
  "version": "1.0.0",
  "description": "A simple library",
  "main": "index.js",
  "scripts": {
    "start": "webpack serve",
    "build": "webpack"
  },
  "dependencies": {
    "react": "^17.0.2",
    "three": "^0.165.0"
  },
  "devDependencies": {
    "webpack": "^5.24.0",
    "webpack-cli": "^4.5.0",
    "webpack-dev-server": "^3.11.2",
    "babel-loader": "^8.2.2",
    "@babel/core": "^7.13.1",
    "@babel/preset-react": "^7.12.13",
    "jest": "^29.7.0"
  },
  "peerDependencies": {
    "react": "^17.0.0"
  }
}

As you can notice, the package.json contains 3 fields that list dependencies. The dependencies listed in each field are meant to be separate, as they are used for different purposes.

A visualization showing the 3 types of dependencies being present in a projectA visualization showing the 3 types of dependencies being present in a project

👉 What are dependencies?

The packages listed as dependencies are essential for the application to run. They are included in the bundle of the application and are expected to be used in production. For example, react and react-dom are dependencies because the app cannot function without them.

👉 What are devDependencies?

A visualization of the different dependencies and devDependenciesA visualization of the different dependencies and devDependencies

The packages that are part of devDependencies are only required during the development phase. They help with testing, building, and linting but are not needed in the production build. Great examples are packages like webpack or babel.

👉 What are peerDependencies?

A visualization of the different dependencies and peerDependenciesA visualization of the different dependencies and peerDependencies

If your library expects a certain dependency to be available in the consumer application, that dependency is placed in the peerDependencies field. This is useful for libraries that need to ensure compatibility with a specific version of a peer package, as it makes sure the dependency used will not be part of the compiled code.

A visualization of multiple react applications using the same shared UI libraryA visualization of multiple react applications using the same shared UI library

For example, if you are developing a React component library, you would list react as a peer dependency. This ensures that the library will work with the version of react provided by the application that uses the library. If another project installs your library, the package manager will warn if the peer dependency constraint is not met:

"peerDependencies": {
  "react": "^17.0.0"
}

Conclusion

By understanding the differences between dependencies listed in your package.json, you can make sure that your project is configured correctly:

  • dependencies — lists the packages required for the application to run in a production environment. For example, styled-components is often used as a styling tool, and it is required to be present in production to style the application correctly.

  • devDependencies — contains the packages needed during the development and build process. webpack, babel-loader, and other packages are listed under this field because they are used to compile and bundle the code, but not required to be present in the production environment.

  • peerDependencies — specifies packages that your project needs, but expects the consuming project to provide. This is mostly used for libraries and shared code.

NxPNPMReact