“Not Invented Here” Syndrome

“Not Invented Here” Syndrome

A couple of years ago I made a short series of notes on the patterns of behavior: Technical Debt, Refactoring Syndrome and The Second-System Effect. The time has come to discuss another subject, probably the most famous and popular pattern of behavior: the Not Invented Here (NIH) syndrome.

Not many people like someone else's code. There are too many letters in it, it’s hard to get to its essence, not all of us can read between the lines, and reading the thoughts of the author without a crystal ball and dark magic rituals is still impossible. Building something from scratch though is a different story: the system is developed in stages, you know the compromises present at every step of the development process and understand why particular decisions were made. You learn because the information about the system neatly falls into place in your head. But once a different person is in your shoes, they, for some reason, do not appreciate your efforts, and strive to throw everything away and rewrite it.

The ones who want to “forget the present and do it their own way” have their own reasons.

First, development from scratch is a lot of fun! It is so exciting to create a concurrent collection, your own message exchange manager, or your own ORM! It is a really cool way to learn something in more detail. However, supporting such creations made by others is not what you would call fun.

Second, you may not know about the existence of a ready-made solution. If you do not know about the existence of ready-made libraries for parsing expression trees, and you have no idea about the existence of expression trees in .NET, it is obvious that you will not try to create your own solution. The example is exaggerated, but it is often our narrow-mindedness which leads us to use improper tools or to invent our own ones.

Third, reusing someone else's solutions can simply be more difficult than developing your own. The main difficulty of reuse is that it should be easy! Nobody wants to use someone else's code, if in order to do this you need to fork three repositories, download two tools for their assembly, and then try to understand other people’s stuff. Some minor issues in using, updating or error diagnostics will exhaust the pragmatism of even the sanest developer!

Fourth, you may think that you can do it better. Nobody can write a proper concurrent collections library, but you can. Nobody can implement their own key-value store, but you can! There are two options here: you have studied different implementations and clearly understand what problems they contain and how to get rid of them. In this case you just don’t carry over the whole baggage of accumulated mistakes of the old solutions and start with a clean slate. You do not use the existing code, but you certainly use your own and others’ accumulated experience. As a result, it might end up as something good and useful for you and for others (Roslyn is an excellent example of this approach).

But usually this all happens somewhat differently: you’ve heard that someone had once toyed with immutable collections and something was wrong with them. And without even trying to understand the existing issues of a ready-made library, you write your own solution. Usually the result is the same soup, just reheated. You just know where to put a crutch for the solution not to collapse completely.

Not Invented Here Syndrome.jpeg


Reuse vs. reinventing the wheel is a typical tradeoff of individual developers, development teams and whole companies. In Microsoft there are 4 different systems for collection and analysis of telemetric data, a dozen clones of IL code analyzers and hundreds or even thousands of implementations of collections of all kinds. And such situations are present in any company.

It is quite difficult to find the proper balance between the approaches "to reuse and bring good to everyone” vs. "to solve the problem here and now". The syndrome of "Not Invented Here" can be viewed as a special case of the “reuse a component” vs. “duplicate the code” problem. In one case it is better to duplicate code and not to introduce unnecessary relations, and in other cases it is better to summarize, create a reusable component and live happily ever after. Yes, it is difficult, but still possible.

The popularity of NuGets and other package managers makes the consumption of third-party components easier and does useful work in terms of reuse. But this interesting mix of programming pessimism ("everyone does everything bad") and optimism ("but I'll do it better"), will never allow the "Not Invented Here" syndrome to disappear completely. And this might be not such a bad thing.

Sergey Teplyakov

Expert in .Net, С++ and Application Architecture