Services like browserify essentially do this for you, as long as you are willing to compile ahead of time (and leave a lot of packages that don't "make sense" on the browser behind).
The idea here of course is that all those packages are usable (so for example if you want to show someone how to take files and zip them, you can). Additionally, it is important not to forget that a package can actually be 20 packages thanks to nested dependencies. A lot of work went into making a system that when you type require("package") works instantly and doesn't have to go and fetch the nested dependencies -- not only that, but shrink-wrapping in the background so that rerunning the notebook is 100% reproducible (not constantly changing underneath you as versions change). With this we also get the really cool ability to not only have every package on npm, but every version of every package. If you look at this example, you'll see we can easily compare two versions of the same package: https://tonicdev.com/tonic/api-diff-example
The idea here of course is that all those packages are usable (so for example if you want to show someone how to take files and zip them, you can). Additionally, it is important not to forget that a package can actually be 20 packages thanks to nested dependencies. A lot of work went into making a system that when you type require("package") works instantly and doesn't have to go and fetch the nested dependencies -- not only that, but shrink-wrapping in the background so that rerunning the notebook is 100% reproducible (not constantly changing underneath you as versions change). With this we also get the really cool ability to not only have every package on npm, but every version of every package. If you look at this example, you'll see we can easily compare two versions of the same package: https://tonicdev.com/tonic/api-diff-example