How Browserify Lets You Use NPM Packages In Simple Websites

I’ve been trying to help my wife use a Javascript package that’s only got npm install as its instructions for how to get started. For people who aren’t JS devs (ie, me and her), that’s not really sufficient to actually get something used in a website the way you would by importing a library.js file using a <script> tag.

There’s a solid StackOverflow answer about how to use Browserify to do this, but there’s not really a great accompanying explanation of why, which made me way more reluctant to just throw command line tools at the problem and made my search take way longer than it needed to.

So here’s my attempt at writing down the why that I’ve figured out thus far, both for others in a similar position and for me when I need to remember how the hell this all works in six months.

As a mobile developer, I at least understood the general concept and purpose of a package manager: It lets you bring in code from other people, specifying what version of that code needed to be brought in. And if the code you’re bringing in needs other code brought in, it brings that in for you, and so forth until all the code necessary to do the thing you’re directly bringing in has been added.

The thing I had an awful time understanding was “Great, OK, so how do I go from that to a website? Do I need to add something weird to the <script> tag for it to see the stuff I’ve pulled via npm? Do I need to upload all of this giant node_modules and set up a node runtime on my server?” (Thank all the deities, the answer to that last one is no).

npm is set up to make it really easy to fetch dependencies for node.js server apps, because you can just use require('libName') and call it a day with the node.js runtime. You need an extra piece of Internet Duct Tape to actually get it into a format where it can just be used in a <script> tag.

This was the thing that really tripped me up: Package managers I’ve used for other languages have generally either not required additional integration under the hood or hidden it so well that I just didn’t think they did. The idea that I had to have a thing that took the output from the package manager and then did more stuff to it to make it work seemed really bizarre to me.

When you learn why, it’s not that bizarre: Basically, code works well in node.js apps because it uses a node.js runtime, which handles the way everything is imported from npm. Browsers don’t have that runtime, so you have to generate a file that says “OK browser. Here is all the code in a format that you understand.”

The thing that generates that file is a tool like Browserify, and by convention the file generated that will have all of your libraries in it is usually called bundle.js. That file is then uploaded to your server, and you can then import it to your HTML using a <script> tag like any other local javascript file.

One thing that some libs do that are frequently used in browsers is include a version of their library under the /build folder when it’s been checked out through NPM that has something that’s already been run through a tool like Browserify and include the output in a /build folder in their npm package.

It turned out the package we were using, Airtable, actually does this, and we could just copy the file straight out of their /build folder and onto the server, import it via a <script> tag, and not even have to faff around with Browserify. It’s just that I couldn’t find a thing on Airtable’s website that even implied this was an option, because the assumption is that everyone already knows that this is an option.

I can’t blame them for that: It’s very, very difficult to write docs for a library that don’t assume at least some basic knowledge of the ecosystem surrounding that library. There are plenty of “explain npm to me like I’m 5″ articles, but most of them focus on the fact that it’s a package manager, and not how it can get things onto a website.

Maybe I need someone to explain how the pieces fit together like I’m ten.