From Not Invented Here to Never Invented Here
“Why didn’t you search NPM for a solution?” Bob asked. Alice thought she was being trolled, but it appeared Bob was totally serious. “Are you kidding? It’s 15 lines of code, and I put it in the shared folder.” Alice responded incredulously. “Yeah but now we’re responsible for maintaining it forever. If you’d used the open source module, maintenance is a problem for someone else” retorted Bob. Alice was speechless, could Bob really think that?
Recently there was quite a dust up in the Node community which resulted in many packages being broken because one developer decided trademark law shouldn’t apply to him. The main pain came from a single 11 line module called left-pad. At least the developer has not removed his packages from GitHub so for the short term, updates to affected packages package.json files should fix the issue. That said, there’s a bigger issue here and this event perfectly illustrates an anti-pattern that’s all too easy to fall into.
Most developers are perfectly reasonable people who use the code of others when necessary and write their own code when necessary. As with many things though, it’s not binary, it’s a spectrum. The spectrum ranges from the Not Invented Here crowd to the Never Invented Here crowd.
Not Invented Here
This crowd refuses to use any software (generally related to their businesses core competency…they aren’t writing their own kernels if they make iOS apps) that wasn’t written in house. They want total control over every bit of code, to whatever extent possible, running in their systems. They would largely have been insulated from recent events. That said, they’d also be insulated from all the benefits that come from sharing code. This includes things like security vetting, public code reviews for quality, etc.
Never Invented Here
This crowd avoids writing code at all costs. They’d rather pull in and integrate a 4 line function from GitHub than write it themselves. The argument here is that every line of code has a maintenance cost associated with it. As such, code is to be avoided (except connector code). This group would be heavily affected by what happened recently. That said, they get the benefits of much lower development costs (in theory anyway) and not having to think too much about how to do things other than hook existing open source together.
Understand Where You Fall on the Spectrum
Good developers mostly accept that “Not Invented Here” is bad. It results in far more costly, slower, less secure development and the on going maintenance cost is far worse as well. Fortunately it’s hard for “Not Invented Here” to creep up on you. If you’re a member of this camp, you pretty much know it. The same can’t be said for “Never Invented Here” unfortunately. It’s easy for “Never Invented Here” to creep up on you, especially in service of avoiding “Not Invented Here”. What people often fail to grasp is that the creep towards “Never Invented Here” is just as dangerous as being a “Not Invented Here” shop (though for different reasons). Never was this better illustrated than an 11 line NPM module breaking many other packages.
Here are some strategies for staying in the “pattern” area of the spectrum and avoiding the “anti-pattern” edges. I use NPM as an example in some cases, but the strategies are generally applicable.
Time Box Searching
If something will take less than an hour or 2 to code and test, don't even bother looking for an existing solution outside of the existing set of libraries you’re already familiar with or using. Just get to work and write some code.
If you believe something will take effort on the order of days to weeks, spend no more than 20% of that time looking for someone else to have already solved the problem. If you can’t find something reasonable (i.e. solves 95% of the issue) then get to work and write some code.
If you decide to use a library or framework because it will significantly improve your time to completion or reduce the risk of some complex code, fork it on GitHub. If the code isn’t available on GitHub, but is open source, mirror it to GitHub (you can do this by adding a new remote and pushing to that remote). Once you have it there, rely on that version as your dependency. Most package managers have a means to specify the source of a code set, in NPM you can do this quite easily (see the many great NPM guides to understand how). While it’s a little more work, this has a couple of immediate advantages:
- You’re insulated from the source repo getting unpublished
- You’re insulated from accidental upgrades (though with package managers like NPM, you can shrinkwrap and achieve this)
To take advantage of bug fixes and new functionality in the package, you can easily pull from the source repo into your fork. It goes without saying that any fixes or additions you provide should be sent as a pull request to the original repo.
Using Open Source Doesn’t Relieve You of Responsibility
An oft cited reason for using open source code over creating your own is maintenance cost. This is also the least compelling reason to use open source code. While using open source may reduce maintenance cost, it’s just as likely to have no effect or increase the cost. The reason for this is that if you discover a bug, you now have a few options:
- Report and wait for the maintainer to fix it (something you have little to no control over)
- Fix it yourself which means you need to spend time reading and understanding the code so that your changes don’t have unintended side effects.
- Try to work around the issue, which may or may not be possible but will definitely result in a less than elegant solution.
As I’ve stated before, a good reason to use some open source package is a significant boost in velocity and/or reduction in risk of security or speed sensitive or otherwise complex areas. You still need to make sure that you trust that it will continue to be maintained, or that you can maintain or replace it yourself in a worst case scenario.
Don’t fall into a Never Invented Here anti-pattern trying to avoid the Not Invented Here anti-pattern. Think before adding a dependency. Only do so when it advantages your project and take steps to insulate yourself from dependency risks described above.
I’m Amir Yasin, a polyglot developer deeply interested in high performance, scalability, software architecture and generally solving hard problems. You can follow me on Medium where I blog about software engineering, follow me on Twitter where I occasionally say interesting things, or check out my contributions to the FOSS community on GitHub.
If you enjoyed this post, I’d really appreciate a recommend (just click the heart below).