In this article I will try and reason about whether it is a good idea using a particular library rather than writing the code yourself. I am trying to be objective but I am sure that my opinions will shine through (yes, I am looking at you, header) on more than one occasion. Please use this article as a source of discussions rather than hard facts (which it is not).
Sometimes it is fine to reinvent the wheel
You are asked to implement new functionality, something that involves solving a problem that does not yet exist in your project. You sit down with your keyboard and start doing your magic, what is the first thing you do?
I feel that a growing number of developers start by asking the web if this particular problem has been solved by someone else, searching for a library or framework that could potentially aid or completely solve the problem. What is the harm in that you might ask, why invent the wheel again?
I work as a consultant, so I have been in my fair share of projects in various organizations and I’m writing this article in light of that, you might not agree with me or haven’t even faced the same problems as the ones I’m writing about. Fair enough, differences in opinions create discussions and reflections. Maybe you have input or thoughts that can make me see all this in a different way?
So, why are developers keen on looking for an existing solution to a problem? I’ll give you a list of things that I believe is the reason (no specific order):
- To save time and money
- To increase maintainability (after all, third party code is maintained by the third party)
- One is unsure of how to solve the problem
- One doesn’t need to understand the problem to solve it
- One thinks that inventing the wheel again is bad and unnecessary
- It is the new cool thing that everyone talks about and I want to try it out
- To reduce code complexity
The ones in italic are reasons that I feel that some developers have but they are not arguments usually given to me when I ask the question to my team members. The other ones however are real arguments that are given to me almost every time, arguments that can all be perfectly valid for using a particular library. When I get these replies I try to be the devils advocate, trying to make them think critically, but it is very difficult for many to understand that a library is not always the best route to take. I think it is because a project must live for an amount of time before the problems start coming and then it is already too late.
Downsides of using too many libraries
If we start using libraries/frameworks to solve all our problems we will eventually end up with a massive amount of them, this means that we need to have the skills to work with and understand all of these which leads to a high maintenance cost and a decreased maintainability of the code base. We need to keep track of version changes which means that we need to take care of breaking changes which might lead to ripple effects throughout the code base, this in turn will create the need to regression test the entire system (or at least where you are using the library). This is very time consuming work and not at all in line with the initial idea to save time. Libraries and frameworks come and they go, the risk of being stuck with something that is not maintained or supported can be high if one is not careful.
Other problems that I see in almost every project is the need of customization, the generic library that seemed so good in the beginning proves itself not specific enough to solve the problem at hand. Customization/extensions/wrappers around a library are especially risky, not only do we need the competence around that particular library, we also need to maintain our code that wraps it. It becomes more difficult to know if a bug lies in our code or in the library. Also, the need for customization can sometimes be a sign of an incorrect understanding of that library – meaning that it is not being used in the manner that the author intended, thus increasing the risk of bugs and other nasty quirks.
Frameworks in particular usually have large footprints. it can have memory footprint (download size and memory usage), an opinionated style of coding, have a steep learning curve or impact performance negatively. One must always weigh the pros and cons, carefully.
Think before acting
How do I think then? How do I answer my own question? I believe that a library/framework should solve a problem that is either too complex or takes too long time to complete and it should do so with the smallest footprint possible. So I always try to understand the problem at hand, trying to grasp what exactly is needed to solve it. Will the solution take a long time to develop? Will it be difficult for others (or myself) to understand it? If the answer is yes, it will take a long time and yes, it will be difficult to understand (i.e. complex) then I will for sure go and look for third party libraries that can solve my problem. I think we all should ask ourselves these questions, and most importantly – don’t be afraid to write your own code, it is fun! Be an inventor, not a composer of libraries.
An easy way to illustrate what I mean is with the graph below, it visualizes the relationship between the time it takes to solve a particular problem versus the complexity of it. If a task lands in the green area (fast and easy) then it is definitely something I would implement myself. If it lands in orange (fast but complex or easy but time consuming) I would think twice before deciding and if it lands in red (complex and time consuming) I would most probably go look for a third party solution.
Okay, I’ll say, this is a big simplification, everything depends, right? What does it mean when someone says it takes a long time or if something is complex? Something that is complex in one project might be below average for another. It all depends on domains. Image processing is probably very complex for an application that just wants to add a cool filter (i.e. Instagram) while it is everyday tasks for Adobe. The same goes for time, if a task is very central to an application it is probably fine that it takes more time compared to something not as important.
Good types of libraries to use
Let’s give some examples of good libraries to use for a fictional application that wants to enhance photographs. This application has a web frontend and an ASP.NET backend (yes yes, I know that .NET is a framework).
- Image processing
We will for sure need something to process images but we don’t have the specialists that can write all the math functions needed to apply filters nor do we intend to hire any to maintain it. This also goes straight to red, something we would like to solve using an existing library.
- UnderscoreJs (or similar)
We need to do array manipulations and object manipulations. I’d say we could implement our own functions to do our sorting and filtering without anyone questioning it. I would argue that this is more towards time consuming than complex. If we need a lot of these manipulations then I’d think twice before implementing it myself, on the other hand, if we only need a few simple methods such as sorting and filtering I’d be happy to implement it myself and be happy that I didn’t introduce yet another library.
- ORM (Object Relational Mapper)
We would probably need to store some information. We just want to store it in a small SQL database and it would be both to complex and time consuming to write our own object to SQL to object mappings, our own transaction handling, our own lazy loading (if one like that sort of thing), etc.
Don’t always use hyped frameworks just because
What about all those other hyped web frameworks and libraries that we developers scream about as soon as there is a fresh new project to begin with? Let’s take two popular web frameworks as examples.
Angular seems to be everywhere I go nowadays and many times it seems to be used just because it is the new cool thing. Did anyone sit down and asked themselves if they really needed all that comes with Angular (a forced way of developing, an easy route to performance issues, difficulties to debug and let’s face it – it is rather complex)? Did they really need the two way data binding or the services/factories/provider stuff? Sometimes a ”solve it all” framework is overkill. Not always, but sometimes. Ask yourself the question. Also, finding Angular specialists is difficult, especially in 5-10 years from now.
This one is really bugging me, the whole web is flooded with websites that looks the same. Boring. I get it, for small, internal applications (or proof of concept applications) it can be a good library to use, one can copy code snippets from the documentation and it just works. However, the code is ugly, not semantic and difficult to learn (try working with bootstrap without constantly looking at their documentation). This example comes from the documentation:
<div class="row"> <div class="col-sm-6 col-md-5 col-lg-6">Some content</div> <div class="col-sm-6 col-md-5 col-md-offset-2 col-lg-6 col-lg-offset-0">Some content</div> </div>
Imagine a code base full with this type of markup, difficult to grasp and not semantic at all. The main reason I’ve heard for using Bootstrap is that CSS is difficult and hard to maintain. I’d say it’s the opposite – Bootstrap will be hard to maintain, it will die, CSS won’t. CSS is not difficult. Write it yourself, it is more flexible, you will get better results. It is good fun.
Don’t always use a library because it is the new shiny thing or the easy and short term way out of a problem. Try and understand the problem at hand, if you code it yourself you will be in complete control of that code, you don’t need to customize or extend, you don’t need to think about large memory footprints, a steep learning curve or an opinionated way of coding that does not fit into the rest of your code base. There are of course times where a library is the correct way to go, when it solves a too complex or time consuming problem. Just ask yourself the question – do I really need this?
(Twitter @aHagsten https://twitter.com/aHagsten)