With npm, each library has its own set of dependencies (and those libraries have their own sets of dependencies, and so on) that are entirely separate. Thus, if you depend on two libraries that use libfoo, those two libraries have their own copies of libfoo - and those two copies can be different versions, if needed (and if libfoo depends on libbar, you'll have two copies of that too). This makes the presence of dependencies much less leaky and eliminates most problems with incompatible gem versions at the cost of wasted disk space, (usually trivially) increased memory usage and some potential confusion. It also happens to make npm pretty mind-numbingly simple compared to bundler's dependency resolution logic.