DEV Community 👩‍💻👨‍💻

Cover image for Difference between Node dependencies using emojis 🤷‍♂️ 🤷‍♀️
D/S
D/S

Posted on

Difference between Node dependencies using emojis 🤷‍♂️ 🤷‍♀️

Node dependencies come in different forms: dependencies, devDependencies, peerDependencies, bundleDependencies and optionalDependencies.

We’ll be tackling the first three in this blog post, which are the ones which interests us the most, but I’ll briefly explain what bundleDependecies and optionalDependencies are.

  • bundleDependencies: these dependencies are the dependencies that will be bundled alongside your library if you run npm pack. From the folks @npm themselves:

"This defines an array of package names that will be bundled when publishing the package."

  • optionalDependencies: are dependencies which are, well, optional. I’ll let myself out 😀. Dependencies installed here will not make the installation of your library fail if they can’t be found. I consider them as the alternate version of dependencies without being so strict. From your friends @npm:

“If a dependency can be used, but you would like npm to proceed if it cannot be found or fails to install, then you may put it in the optionalDependencies object.”

🚨 Keep in mind that you have to specify either dependencies or optionalDependencies but not both 🚨

“Entries in optionalDependencies will override entries of the same name in dependencies, so it’s usually best to only put in one place.”

With that out of the way, let’s get rolling with the other three sort of dependencies node give us.


If you have come across a package.json in your programming day(s), you’ll probably have seen a dependencies, devDependencies and/or even perhaps their step cousin, the peerDependencies object, a.k.a 🍐Dependencies.

…get it, get it ?…cause it sounds like 🍐… ok, I’ll stop now... 🙂

This last one, usually comes in the flavor of a warning while you try to install x package. Usually in the form of:

the package 'x' has an unmet peerDependency of 'y@1.0.0'

You might be wondering, how are these things even related? Let’s look at all three of them by creating our own “Making a Burger 🍔” library.

// pseudo package.json with some emojis

{
 “name”: “making-a-burger”,
 “version”: “1.0.0”,
 “description”: “🍔 lib”,
 “main”: “index.js”,
 “author”: “🙋‍♂️”,
 “license”: “MIT”,
 “dependencies”: {
   “🥩”: “meat@2.0.0”
  },
 “devDependencies”: {
   “🥚”: “egg-yolk@1.O.O”
  },
 “peerDependencies”: {
   “🍞”: “>= bread@1.x”
  }
}

In actual words this could be translated onto …

  • dependencies: hey, to make this 🍔 library (a.k.a run a burger) you must have 🥩 on hand. The library runs on it… (except if you are making a veggie burger 🚫 🐮, of course).

A good example would be things like vue, react, react-native, eslint (if making a shareable eslint-config file), etc.

  • devDependencies: yo, while developing that 🍔 you better have an 🥚 on hand since this will ease the process… (and give flavor to your food 😋…and maybe salmonella if you don’t cook it right… ?).

Packages that work on the modification/manipulation/testing of your original code are a good example for this type of dependency: @babel/*, webpack, jest, etc.

  • peerDependencies: bro/bro-ette(…🤔 ?), don’t be trying to make this 🍔 library without having some 🍞 also in hand at equal or greater than version 1.x….(version gluten-free, normal, whole-grain…ok, this one is actually a pretty bad joke).

This last one is the most interesting one. We specify peerDependencies to let users of your library know that they must have this minimum version of this other dependency also installed, because the overall library runs on them. In other words:

package ‘x’ also depends on having package ‘y@1’ installed.


And just to do a complete circle, 🙂 if we were going to add optionalDepedencies and bundleDependencies to this library they will be on the form of:

{
 “name”: “making-a-burger”,
 “version”: “1.0.0”,
 “description”: “🍔 lib”,
 “main”: “index.js”,
 “author”: “🙋‍♂️”,
 “license”: “MIT”,
 “dependencies”: {
   “🥩”: “meat@2.0.0”
  },
 “devDependencies”: {
   “🥚”: “egg-yolk@1.O.O"
  },
 “peerDependencies”: {
   “🍞”: “>= bread@1.x”
  }
 “optionalDependencies”: {
   “🥬”: “lettuce@3.2.x”
  },
 “bundleDependencies”: [
   “🍟”, "🥤"
  ]
}

I guess that’s it, I hope this have been somewhat helpful or at the very least fun.

If you want to learn more about node dependencies and all the goodies that go inside a package.json, don’t forget to take a look at the npm-docs cause it’s filled with useful info.

Thanks for reading and if something is not clear shoot me a comment. All feedback is welcome.


Note: As I finished writing this, I realized that a better example for devDependencies would have been a meat grinder (?), but I couldn’t find that emoji 😔 .

Top comments (2)

Collapse
 
sunnysingh profile image
Sunny Singh

This cracked me up, while also teaching me about optional and bundle dependencies, I didn't quite understand what they did until now. I'm hungry for some more emoji posts now!

Collapse
 
intercoder profile image
D/S Author

Thanks @Sunny Singh glad that it help aaaaannnndddd that it made you hungry for more emojis. We always need more emojis 🙂 🤷‍♂️

Need a better mental model for async/await?

Check out this classic DEV post on the subject.

⭐️🎀 JavaScript Visualized: Promises & Async/Await

async await