Different types of dependencies in a Node.js application explained

Abhishek Singh
JavaScript in Plain English
6 min readDec 23, 2019

--

Photo by Markus Spiske on Unsplash

In the cycle of creating or using node js projects every developer once in a while encounters the phrases like:

npm i package_name
npm i package_name --save-dev
npm i package_name -g

Now there are other flags as well like:

P.S. i is shorthand for install

npm i package_name --save-optional
npm i package_name --no-save

What are the meaning of these flags? How these commands shapes our project?

Answer to these question lies in package.json file. When we create a node js project we use the command: npm init in our project folder which leads to certain questions and ultimately creates package.json file or if we download a node js project we always find this file in project’s folder.

Now this file contains a lot of information about the project, like project’s name, version, entry point(main), scripts, author, etc. but critically it contains the information about project’s dependencies if any. When a user distribute his/her project, then the first command that recipient of the project run is: npm install or some script that essentially calls this command. It is a part of setting up the project. What this does is the node package manager(npm) looks into the package.json file and installs all the dependencies listed in package.json file. But there are more than one type of dependencies.

  • dependencies(production dependencies)
  • devDependencies(development dependencies)
  • optionalDependencies
  • peerDependencies
  • bundledDependencies

Production dependencies

Production dependencies are normal dependencies that are mandatory for running the project. These are the packages that are being used in the code of the project. For example if my application is working with mongoDB then there may a dependency of mongodb node package in my application.These dependencies are specified under the key “dependencies” in package.json file. And developer may use

npm i package_name
// or
npm i package_name --save-prod

to install them. An application won’t work as expected if all the dependencies under “dependencies” key in package.json file are installed.

Development Dependencies

Next are development dependencies, these are those dependencies which are needed at the time of development but are not responsible for working of the application i.e. even if we skip these dependency our application will work just fine. One such most common is nodemon which

is a tool that helps develop node.js based applications by automatically restarting the node application when file changes in the directory are detected.

Nodemon might be helpful while developing the application because it saves us from starting our application again and again when we make some changes but is usually of no use when we deploy our application because the user/deployment-environment has to start our application once as no changes have to be made at the instance of time when the sole purpose is to use the application and not modify it. Developers may use the following command to install the package as development dependency.

npm i package_name --save-dev

By issuing this command, once the package is installed, the package.json file will be modified and this package with it’s version will be saved under the key “devDependencies” .

Optional Dependencies

Optional dependencies are those dependencies which as the name suggest are optional i.e. these dependencies won’t cause a installation fail while installing the dependencies for an application/project as npm will ignore these dependencies if these failed or are not found. The application will run just fine with or without these dependencies.

Now to make things clearer consider this scenario, suppose you are making a node script that takes some input and logs multiple custom outputs on console. The console logs are same in color and for distinguishing between the logs you are using chalk as a dependency that helps you style the logs but when you distribute this script/app it isn’t necessary but possible that the recipient/user of the script/app might use chalk to style the logs as well. This will make chalk an optional dependency for this particular case. This dependency should not break the working of the script/app as it purpose was to console the logs not style them. One thing to remember when using a dependency as optional is, it is still your program’s responsibility to handle the lack of the dependency. If you need further assistance in this task read here. To make a dependency optional developers can use the following command:

npm i package_name --save-optional

This will lead to your package appearing under “optionalDependencies” key in package.json file

Peer Dependencies

These are used when you are developing a plugin/package for a host tool or package. That means you expect the user of the plugin/package to have these dependencies installed while not necessarily using these dependencies in your in your plugin/package. For example if I am making a hypothetical plugin/package named “electric-car version 1.2” for a hypothetical host tool or library named “car version 3.5.0” then I will specify the package “car” with version 3.5.0 under “peerDependencies” key in my package.json file. And user is expected to have these host dependencies installed before installing/using the plugin for the host tool or library. Keep in mind running npm install from plugin directory won’t install these packages.

Bundled Dependencies

These are array of packages which are bundled when publishing our package.If you want certain or all the dependencies bundled together in a single file then you can specify these dependencies under the key “bundledDependencies” in your package.json file. To actually create a single tarball of all the dependencies mentioned in bundledDependencies you issue the command: npm pack which will create a .tgz file with name like: name_of_the_project-version_of_the_project.tgz. After this is users can simply issue the command npm install name_of_the_project-version_of_the_project.tgz to install the project bundled dependencies using a single file. This approach is used when we want to preserve our dependencies and make them available using a single file.

— Bonus —

When developers work on node js application they sometimes use the following command:

npm i package_name -g

This command is use to install a node js package as global dependency that means this package is installed globally and can be used from any application/project using the developer’s machine only, these are frequently used packages which are never used by any particular app/project. Therefore when installing these modules they never come under any dependency in package.json file, in-fact these never leads to any modification in package.json file. These are usually the packages which provides developers with certain utilities that are frequently used in development but are almost never needed in production. Some examples are create-react-app package which is used to create a react app skeleton of react app without build configuration for initial setup and packages like nodemon can also be installed globally.

Sometimes you might also encounter this command:

npm i package-name --no-save

What this does is that it installs package to use in the project but not as dependency. These package are disposable, application doesn’t depends upon these packages and they are not listed under any dependencies in package.json file just like global packages installs.

But the main difference is that global packages can be accessed from anywhere(any project) via node, the packages installed with — no-save flag can only be accessed from that particular project only from which the command was issued.

Package.json vs Package-lock.json

These 2 files are there the heart of dependency management in node js applications.

Package.json file is used to have more information about project and package-lock.json has more information about the dependencies. Package.json file contains information about all kind of major dependencies like if my application uses express as a devDependencies it will be listed in package.json file but express itself has 30 dependencies and 18 devDependencies, these with all the information like version, integrity, etc. will be listed in package-lock.json file. So when npm install command is issued npm make use of these files to create a fully function build and install the dependencies accordingly.

So that’s all folks. I might I have missed some points but roughly that’s about it. And I just want to make sure that the packages that I have mentioned here like nodemon, chalk, express, mongodb, etc., I am not here to promote them in this article I mentioned those simply because I extensively use them and they make my life a little easier. Please leave a clap if you found the article helpful.

Feel free to reach me out on other social platforms like Instagram, LinkedIn, Facebook, I am always up for an intellectual conversation, Have a great weekend and happy coding 😉.

--

--

Computer enthusiasts who loves coding💻 and photography📸 Pythonista🐍 Full stack developer