“All things are poisons, for there is nothing without poisonous qualities. It is only the dose which makes a thing poison.”
As the open-source movement will only grow stronger in the coming years, it is no surprise that software engineers will work with more and more libraries throughout a software development process.
However, as awesome as libraries are, their unstoppable growth has left me with a question: are modern software engineers relying too much on third-party libraries?
Well, in my opinion, yes and no.
Just like all problems in computer science, the answer is not that straightforward. We need to take a step back and have a clear understanding of why we use software libraries in the first place.
Why use libraries?
Software libraries implement a pattern known as abstraction. They essentially cover up complex implementation details and expose interfaces that your software can interact with.
Think of it as your smartphone. Do users need to know how a phone call is made? For most people, they don’t. All they have to know is that the features they desire work correctly, as long as they use them within any constraints.
This behavior can be observed in how we utilize software libraries as well.
Need to generate random dog photos in Python? Well, here is a
dog library for you. Just import this
random_dog function, call it with the required parameter, and tada! You get the cute dog image you want for whatever reasons.
How was the dog image generated? Is there a database of images stored elsewhere? There is no need to know. In most cases, the program does not matter, it’s the output that brings value to you.
What if you have ten other Python applications that require dog photos? That wouldn’t be a problem, just import from the library and call the function again!
Just like our smartphones, software libraries provide reusable functionalities that we require as engineers on a day-to-day basis. Instead of worrying about recurring problems, we can focus on developing the core values of our applications.
Overreliance is bad
Need a solution? This library works… right?
As convenient as libraries are, it is usually a bad practice to treat them as silver bullets to all your software challenges.
When I was starting in software, my first approach to solving a problem was to search for a library. I was quick enough to jump onto any libraries that I found without careful considerations.
Over time, I have learned that this practice is not sustainable. If you are not careful, it could accumulate technical debt and undermine your problem-solving skills in the long run!
Quantity ≠ Quality
Yes, there are tons of libraries out there, but that does not indicate anything about their quality.
Many of these libraries are created and maintained out of the goodwill and passion of the software community without strict obligations.
Because of that, some libraries may no longer be under active development. They could be using outdated versions of languages and frameworks, or they have accumulated a long list of unresolved issues and bugs.
In some cases, the main contributors of the library have moved on to other projects without any “successors”. If you are unlucky, you will be left with poor documentation and convoluted source code that you will spend days trying to understand.
When your software uses a library, you have given up a part of your application to a third party. You are forced to assume liability for code that you have not written. You never know when you will be hung out to dry!
Ignorant of fundamentals
Imagine a day where a library that your application feature depends on is deprecated and no longer relevant.
You, as the unlucky engineer in charge, are tasked to recreate a similar library as there are no other alternatives in the market. Would you be able to do it?
Many software engineers use libraries freely while being ignorant of important fundamentals. If libraries are taken away and you are incompetent without them, then you are in big trouble!
Without a fundamental understanding of the concepts behind a library, you can’t utilize it to its maximum potential. Moreover, you won’t be able to make comparisons between libraries and choose the best one for the job.
Software libraries come and go, but their technical fundamentals always remain consistent. Ignorance makes you less adaptive to the fast-changing tech industry!
Working with libraries the right way
Software libraries are like double-edged swords. You reap the benefits if you use them the right way. They stab you in the back if you misuse them.
Throughout my journey in software, I have developed two simple practices to ensure that I always utilize software libraries to my advantage!
Before I install a library, I always make sure I have a good understanding of the technical concepts involved and their implementation details.
For example, user authentication is a must-have in most modern-day web applications. There are many libraries out there that provide well-tested authentication methods.
It is fairly easy to incorporate user authentication into your application with the help of libraries. However, different authentication methods have their advantages and caveats. Such information is usually beyond the interfaces that the libraries provide.
If my users sue me for a data breach, I do not have the luxury to point fingers at a library. I can only blame myself for a lack of research and knowledge!
After gaining sufficient knowledge and knowing what I want, I will look for a list of libraries that satisfy the needs of my application. The qualities of these libraries will be evaluated based on three main factors before a final decision is made.
A library with bad documentation is like IKEA furniture without a user manual. You know it does something, but you don’t know how to make it work.
Good documentation is simple yet comprehensive, and it remains consistent and updated across different versions of a library.
It explains the purpose of functions or classes that the library provides along with any parameters and returned data. It tells you how to work with them correctly within any constraints.
As an example, the documentation of
random_dog would look something like this:
If you use a library with bad documentation, you will waste time going through iterations of trial and error just to get things working. It will be tough to debug any errors that you encounter as well.
A good software library should be specific enough to solve a problem, but flexible enough to support basic customization.
Back to the
dog library above as an example, it would be extremely helpful if it exposes some options for me to alter the size of the returned image!
If all things are equal, always go for a library that supports customization. This future-proofs your application against unexpected changes or new user requirements!
The source code of most modern open-source libraries lives on platforms like GitHub and BitBucket. These platforms provide a feature known as issues, which is a space for discussions about a particular library.
I know, the word “issues” sounds negative. However, a library with many “issues” doesn’t mean it is bad. It could be a positive sign of interest by the community and many people are working together to improve the library!
Issues are also useful to learn more about other engineers’ experience with a library and the challenges they encounter. You can also get a sense of where the library is heading in the future.
A huge number of unresolved, bug-related issues also serves as a red flag. The library could be broken in many ways and the contributors are too slow to fix them.
Software libraries are here to stay. It is up to us to use them responsibly.
Our duty as software engineers is to transform and display various forms of data such that they bring business value to our users. The general public is not concerned with the technical complexities hidden in our applications.
This is why we rely upon software libraries so that we speed up and simplify our development process.
However, I strongly believe that our value as software engineers comes from the ability to understand and create abstractions instead of using them blindly. To grow as engineers, we should strive to progress from being library consumers to creators!
Thank you for reading. Peace ✌️!