Advantages of bundledDependencies over normal dependencies in npm

48,361

Solution 1

One of the biggest problems right now with Node is how fast it is changing. This means that production systems can be very fragile and an npm update can easily break things.

Using bundledDependencies is a way to get round this issue by ensuring, as you correctly surmise, that you will always deliver the correct dependencies no matter what else may be changing.

You can also use this to bundle up your own, private bundles and deliver them with the install.

Solution 2

For the quick reader : this QA is about the package.json bundledDependencies field, not about the package.

What bundledDependencies do

"bundledDependencies" are exactly what their name implies. Dependencies that should be inside your project. So the functionality is basically the same as normal dependencies. They will also be packed when running npm pack.

When to use them

Normal dependencies are usually installed from the npm registry. Thus bundled dependencies are useful when:

  • you want to re-use a third party library that doesn't come from the npm registry or that was modified
  • you want to re-use your own projects as modules
  • you want to distribute some files with your module

This way, you don't have to create (and maintain) your own npm repository, but get the same benefits that you get from npm packages.

When not to use bundled dependencies

When developing, I don't think that the main point is to prevent accidental updates though. We have better tools for that, namely code repositories (git, mercurial, svn...) or now lock files.

To pin your package versions, you can use:

  • Option1: Use the newer NPM version 5 that comes with node 8. It uses a package-lock.json file (see the node blog and the node 8 release)

  • Option2: use yarn instead of npm. It is a package manager from facebook, faster than npm and it uses a yarn.lock file. It uses the same package.json otherwise.

This is comparable to lockfiles in other package managers like Bundler or Cargo. It’s similar to npm’s npm-shrinkwrap.json, however it’s not lossy and it creates reproducible results.

npm actually copied that feature from yarn, amongst other things.

  • Option3: this was the previously recommended approach, which I do not recommend anymore. The idea was to use npm shrinkwrap most of the time, and sometimes put the whole thing, including the node_module folder, into your code repository. Or possibly use shrinkpack. The best practices at the time were discussed on the node.js blog and on the joyent developer websites.

See also

This is a bit outside the scope of the question, but I'd like to mention the last kind of dependencies (that I know of): peer dependencies. Also see this related SO question and possibly the docs of yarn on bundledDependencies.

Solution 3

Other advantage is that you can put your internal dependencies (application components) there and then just require them in your app as if they were independent modules instead of cluttering your lib/ and publishing them to npm.

If/when they are matured to the point they could live as separate modules, you can put them on npm easily, without modifying your code.

Solution 4

I'm surprised I didn't see this here already, but when carefully selected, bundledDependencies can be used to produce a distributable package from npm pack that will run on a system where npm is not configured. This is helpful if you have e.g. a system that's not networked / not on the internet: bring your package over on a thumb drive (or whatever) and unpack the tarball, then npm run or node index.js and it Just Works.

Maybe there's a better way to bundle up your application to run "offline", but if there is I haven't found it.

Share:
48,361
balupton
Author by

balupton

Before I die, I wish to see everyone enabled to do what they love, share their love with the entire world, and live well. This is a big calling, and I'm chipping away at it steadily. This has worked well for me so far; for several years I was the most active Open-Source developer in Australia and one of the most prolific in the world; my technical projects have been used in some of the world's biggest web-sites/apps (Basecamp, Spotify, Ustream) and by some of the world's biggest companies (Microsoft, Adobe, GitHub, Atlassian), touching their millions of users; my non-technical projects have also seen adoption over the years. The key skill set I've used to accomplish this is my natural ability to quickly understand complex systems and simplify them in disruptive ways, a burning need to do good in the world, and an instinctive tenacity for always finding a way even in the most difficult of situations.

Updated on July 08, 2022

Comments

  • balupton
    balupton almost 2 years

    npm allows us to specify bundledDependencies, but what are the advantages of doing so? I guess if we want to make absolutely sure we get the right version even if the module we reference gets deleted, or perhaps there is a speed benefit with bundling?

    Anyone know the advantages of bundledDependencies over normal dependencies?

  • jojackso
    jojackso almost 9 years
    "including the node_module folder" - it's a pretty strange thing which pollutes your repo with generated code... especially when you are working with native modules...
  • nha
    nha almost 9 years
    @Olexandr Between that and risking that a package breaks you app, I guess the choice is easy. Note that you could put in a separate branch (if using git for instance). Agreed, it is far from an ideal solution.
  • Kevin Ghadyani
    Kevin Ghadyani over 8 years
    How does it always delivers the correct dependencies? Does this means npm update won't affect any dependencies in bundledDependencies?
  • Julian Knight
    Julian Knight over 8 years
    Yes, correct. Note that the bundled dependencies might not be "correct" in any fundamental way. They are just what the person doing bundling SAID was correct.
  • Jamie Mason
    Jamie Mason almost 8 years
    I would recommend against checking in node_modules because of packages like phantomjs for example, which install the appropriate binary for the current system. This means that if one Dev runs npm install on Linux and checks in node_modules – it won't work for another Dev who clones the repo on Windows. It's better to check in the tarballs which npm install downloads and point npm-shrinkwrap.json at them. You can automate this process using the npm install -g shrinkpack tool.
  • nha
    nha over 7 years
    @fold_left nice lib, thanks for pointing it out, that seems a superior approach than checking the node_modules folder. The real problem for me is that it is possible to unpublish a package from npm (docs.npmjs.com/cli/unpublish), and therefore that there are no guarantees at all that the packages referenced will still be there in the future.
  • Jamie Mason
    Jamie Mason over 7 years
    Thanks @nha, your be protected from that with shrinkpack also, as the registry tarballs would be in your project repository.
  • nha
    nha over 7 years
    @fold_left yes indeed, thanks for pointing it (and for making shrinkpack). I was just saying that all this could have been avoided if the npm registry was acting like an immutable datastore.
  • Julian Knight
    Julian Knight about 6 years
    Maybe because you are looking at an answer that is five and a half years old! The amount that Node.JS has moved on in that time is phenomenal. Perhaps you would like to add something useful as a comment instead?