Configuration files, npm modules and lost sleep — why publishing front-end modules is painful, and how to make it fun again

Writing front-end javascript libraries is a lot of fun. Having people use the stuff you’ve published is even more rewarding. But bundling and releasing these modules is a huge pain, and the more build tools which make it into the javascript ecosystem, the harder it becomes.

First you start coding. You throw some code into a javascript file, because, obviously, that’s the most fun part. You tweak it and get it working pretty well, and then you think “people might like this! — maybe I should distribute it and make it open-source!”

Then the actual fun begins.

You realize your little file has grown into the hundreds of lines, so you decide to split it up into modules so you actually have a chance of maintaining it in future. Now all of a sudden you need some kind of bundler, so you dust off webpack and desperately search for an old config file to copy, so you can unlock webpack’s secrets and create a nice minified script to distribute.

Next, you realize you want to target older browsers, so people can actually use your code . You’ve written in ES2015 features like let, arrow functions, and object destructuring, which probably work in the newest versions of Chrome, Firefox and Safari but none of the older browser versions (which you totally forgot to test in). So you layer on Babel, eventually get it configured in a way that seems to work, and you compile everything down to ES4 at build time.

After a few seconds congratulating yourself, you realize people are going to freak out if you release any kind of open-source code without including at least a few tests, so you break out Mocha and start writing some, because you forgot to start with test-driven-development (again).

After a while, you realize that running your tests in plain old Node isn’t going to work, because you’re using a bunch of browser-specific apis and features, and you don’t really want to mock all of them out. So you break out Karma and PhantomJS (or Headless Chrome), and throw your tests into a real browser to get them passing — that is, once you figure out how to get Karma to play nicely with Babel.

Suddenly you realize you have no idea how much of your code your tests are actually covering, so you figure: let’s throw in some code coverage tooling and find out! You add in istanbul, and after wrestling to get that, Babel, and Karma to all play nicely together, you save your latest ungodly mess of configuration files, and grab another cup of coffee.

You decide that now you have all of these tests, you might as well actually run them in some kind of CI, otherwise they’ll probably never get run. So you desperately hunt for an old Travis config file you can copy into your project, and tweak it to work with your codebase.

After all that, you realize that even with good tests, people are still going to make pull requests to your shiny new open-source module with changes that don’t follow your coding style, or worse, code that introduces subtle bugs. So you add in ESLint and configure a bunch of rules to make sure any new code follows the style of your existing code. If you’re lucky, maybe you’ll even catch a few bugs at build time for good measure.

Catching bugs at build time makes you greedy for more static analysis. Let’s catch even more! So you decide to try adding Flow (or TypeScript), and then you go the whole hog, static-typing all of your code and destroying null pointers before they even get a chance to rear their ugly heads.

You now have about a million build-time tasks, so you do what all the cool kids are doing and group them into some handy npm tasks.

Finally you’re ready to release your code! — but … it’s late, and you’re sleepy, so it’ll have to wait until tomorrow.

By this point, we’ve spent more time setting up our build than actually writing code. This is one of the reasons many people complain about fatigue from the huge ecosystem which has grown around javascript; not only are there hundreds of front-end UI frameworks to decide from, but even getting a sane, stable build environment involves filtering through a huge variety of build tools, then spending a long time configuring them to work together seamlessly.

I was finding myself spending way too long doing this. So I threw together a boilerplate module called grumbler, which I believe combines some of the best build tools out there, allowing you to just write code and forget about the details of building and distributing.

  • Fork it
  • Start coding!

It’s a fairly opinionated template for distributable front-end javascript modules. It comes prepared with all of the build-time modules I mentioned already, and they’re all set up to work seamlessly together, so you can fork it and start coding right away, without worrying about spending hours writing configuration, and making different tools all play nicely together.

If you do like setting up your own build, or you have your own specific choices for which tools to use, this module probably isn’t for you. But for everyone else, if you want to save time researching and integrating all of this stuff, grumbler might help kick start your project with a pretty small amount of effort.


works for PayPal, as a lead engineer in Checkout. Opinions expressed herein belong to him and not his employer.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store