Relying on reimplementation, copy-paste, npm shrinkwrap, or various other ways of importing third-party code into your repository results in the following advantages:
1. You know exactly what goes into your product, and can audit everything for security, performance, or coding standards.
2. You often end up importing less, as third-party modules may have functionality that you don't need but other clients do.
3. You can modify the resulting code to add showstopper functionality, even if upstream doesn't want to.
4. You aren't subject to the whims of someone removing your dependency from the Internet or replacing it with a version that does something you don't want.
Relying on lots of little libraries installed via package manager gives you the following advantages:
1. You can easily install & try out modules that other people have written, letting you test out new features on users more quickly.
2. You can share code with other modules that have the same dependencies, often reducing the overall size of your system. This is important when there's a cost (eg. download size) to your total bundle.
3. You have less code for your engineers to read & maintain.
4. You can easily track licensing & contact information for your dependencies.
5. You automatically get any new features released by your upstream dependencies.
6. You automatically get security updates and performance enhancements released by your upstream dependencies.
The last is nothing to scoff at: imagine if the headline, instead of 'left-pad breaks the Internet!', had been a security vulnerability in left-pad which literally broke the Internet. Imagine how hard that would be to fix if everyone had copy/pasted the code or re-implemented it. This is not an academic scenario either: remember "Nearly all binary searches and mergesorts are broken", published by the guy who wrote the broken binary search implementation in the Java standard libraries?
http://googleresearch.blogspot.com/2006/06/extra-extra-read-...
Always copying your dependencies into your source tree is not the answer to this, no more than always relying on npm modules was the answer to updating your dependencies. They both have pluses and minuses, and if you really want to be a good programmer, you need to weigh both of them. For my projects, I tend to use whatever libraries I need when building them out (via npm, if possible), and then periodically audit the dependencies to make sure I'm still using them and they wouldn't be better off incorporated directly into the project. I wish more products did this, but I don't control what other programmers do.