So let’s break this down:

“Does functionally work”. Yes, NPM modules, for the most part, do work. This is kind of a given as you wouldn’t include code in your project that doesn’t work. (However, you will run into bugs eventually in the modules you include. And then the fun of debugging other people’s code starts…) And when a developer decides to update a module but doesn’t adhere to semver semantics, well, good luck. (Yes, this can happen with any packaging system, and indeed it happens to me for example with Ruby’s gems from time to time. However, the amount of gems included in projects is relatively small compared to JavaScripts’s “everything-in-modules” approach which geometrically increases the chances of something breaking.)

“Is performant” is the first hurdle. While the code itself probably is fine (though you won’t know until you measure it yourself), it has to be pulled in from a central repository, and it has to be kept up-to-date, which adds extra time during development and later issues when deploying (imagine the repository is temporarily down, the package is no longer available, something broke in a minor or patch release, etc.). You’ll need a build system, and you need one that offers workarounds for these problems (like local caches). In essence, this is adds complexity. And complexity is the enemy of productivity.

“Is relatively easy to understand” is where it gets hairy. Every library and module you add to your code basically creates a black box where input goes in and output comes out and in-between there’s magic. Magic that you have to go in and understand to see if the modules actually behave like you think they do. This package for example, provides a method that cuts off a string at a given maximum length and adds an ellipsis. Now, to find the package, add it to your build system, review the code if it actually does what you want—is it worth using a module? For something you can implement in one line of code?

“Not taking too long to implement”—how long would it take you to write a function that cuts off a string or checks if a number is positive or adds left padding? Many functions you’ll find in a standard library are likely trivial in nature, but having an agreed-upon standard API to do things will speed up implementing code (fewer instances of “is there a library for this or should I code it myself”). Bonus: other people reading your code can concentrate on learning about dependencies that actually matter instead of the 5th implementation of “leftpad”.