An Overview of Dependencies

Ken UdehKen Udeh
5 min read

The role of a dependency in programming is analogous to that of beams and columns in a building. Just as beams and columns form the backbone of any structure, dependencies provide the foundation for building and running software. They simplify the software development process by offering ready-made functionalities that developers can leverage.

Given this critical role, it is essential for developers to thoroughly understand what dependencies are and how to integrate them effectively into projects. This article provides a broad overview of dependencies, their main categories, and common examples. However, it will not cover less common forms of dependencies, such as optionalDependencies and bundleDependencies.

What is a Dependency?

A dependency is an external package, resource, or piece of code that a software program relies on to function. For example, consider a program named A, which includes two subprograms, B and C. These subprograms contain functions, variables, or files that program A needs to execute properly. If program A cannot access the functions and variables defined in B and C, it will encounter errors. Therefore, B and C are dependencies for program A.

Types of Dependencies

In software development, dependencies are generally categorized into two broad types:

Direct Dependencies

Direct dependencies are the packages or resources that a codebase uses without the involvement of intermediary packages. Functions, variables, or files from these resources are directly incorporated into your code. Examples of direct dependencies include production dependencies, which are essential for the software’s functionality in a live environment, and development dependencies, which are needed during development.

Indirect (or Transitive) Dependencies

An indirect or transitive dependency occurs when a dependency with its own dependencies is included in a codebase, creating a chain of dependencies. This results in an indirect relationship between the codebase and the dependencies of the included dependency. An example of this transitive dependency arrangement can be seen with peer dependencies.

The upcoming sections will explain the examples of direct and transitive dependencies mentioned above in more detail and show you how to import them into a project

Production Dependencies

Production dependencies are the packages an application requires to function outside the development environment. In codebases, they are often simply referred to as "dependencies." Common examples of production dependencies include Bootstrap and React.

How to Install a Production Dependency

To install a package as a production dependency, run the following command in your terminal:

npm install <package-name> --save-prod

The --save-prod flag is optional because npm includes this flag by default when you run the command. Therefore, you can omit the flag and rewrite the previous command as follows:

npm install <package-name>

You can also manually install a production dependency. For example, in a React project, you can do this by following these steps:

  1. Open the package.json file in a code editor.

  2. Add an object named dependencies.

  3. Within the dependencies object, add a dependency and its version number as a key-value pair, as shown below:

"dependencies": {
    "dependency_name": "version_number"
  }

Development (or Dev) Dependencies

Development dependencies are packages required only for local development and testing. Examples include testing tools like Jest and Enzyme, and code linters such as ESLint and StandardJS.

How to Install a Development Dependency

To add a package as a development dependency, run the following command:

npm install <package-name> --save-dev

Unlike production dependencies, you must include the --save-dev flag when installing development dependencies. You can also add a development dependency manually. For example, in a React project, here’s how to do that:

  1. Add an object named devDependencies to the package.json file.

  2. Within this object, list your packages and their version numbers as key-value pairs, as shown below:

"devDependencies": {
    "enzyme": "^3.11.0"
    "your_devDependency": "version_number"
  }

Peer Dependencies

Peer dependencies let developers specify the host environment a package is compatible with. For example, if you publish a package to the npm registry and list React version 2.0 (or higher) as a peer dependency, it means that anyone using your package must also have React version 2.0 (or higher) installed in their project.

Unlike production and development dependencies, package managers like npm do not automatically install peer dependencies in a project. Instead, they issue a warning if they cannot find a listed peer dependency or encounter an incompatible version. The following snippet shows React listed as a peer dependency:

"peerDependencies": {
    "react": "^2.0.0"
  }

Moving Packages Between Dependencies

You can move packages between development and production dependencies. For example, to move a package from development to production, run the following command in your terminal:

npm install <package-name> --save-prod

Conversely, to move a package from production to development, run:

npm install <package-name> --save-dev

Common Questions About Dependencies

This section addresses some of the most frequently asked questions about dependencies.

  • Can React be a dev dependency?

    Yes, React can be listed as a dev dependency. This does not prevent your app from compiling because Webpack, used by React for bundling, processes the import statements in your code regardless of React's placement in the package.json file.

  • Do dev dependencies go into production?

    No, devDependencies are meant for development purposes only and do not go into production.

  • What is the difference between a dependency and a peer dependency?

    A dependency is a package that an application needs to run in production. In contrast, developers use peer dependencies to specify the host environment with which a package is compatible with.

Final Words

In this article, you explored the concept of dependencies in software development, including their major categories and examples. While other types of dependencies exist beyond those covered here, you now have a solid understanding of the most important ones. Properly grouping dependencies in your project enables package managers to install the necessary packages and environments for your app to run efficiently, thereby reducing bugs and easing maintenance.

0
Subscribe to my newsletter

Read articles from Ken Udeh directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Ken Udeh
Ken Udeh

API technical writer.