In this post, we’ll explore the considerations behind choosing between leveraging external libraries and creating your own, highlighting the benefits of the latter in deepening your understanding of the problem domain.
The Decision to Go It Alone
When existing libraries are available, opting to write your own is sometimes viewed with skepticism, earning the label "not invented here." But what drives this decision, and is it ever justified? Understanding the motivations behind this choice can provide insight into the trade-offs involved in software development.
The Risks of External Libraries
Reuse sounds great, but it still comes at a cost:
-
Lack of Control
-
Upstream changes can force you to make changes in your own codebase
-
Security and Licensing Concerns
-
Limited Extensibility and Bug Fixing (especially with non-open-source libraries)
-
-
Inadequate Alignment with Specific Needs
-
Often Poorly Documented APIs
To illustrate, consider a project that relies heavily on a third-party library for core functionality, only to find the library’s development has stalled, leaving critical bugs unfixed.
When to Use an External Library and When to Write Your Own
Challenges in Selecting a Library
Initially, the problem you’re trying to solve might not be well understood, making it challenging to:
-
Select the Right Library from Available Alternatives
-
Even Find Suitable Libraries in the First Place
The Benefits of Self-Implementation
Even when a library is found, significant time is invested in:
-
Learning to Use and Adapt It to Your Specific Use Case
However, this process may not necessarily deepen your understanding of the underlying domain problem — a crucial aspect of writing good software.
In contrast, implementing the solution yourself can:
-
Provide an Excellent Way to Understand the Software and Its Domain
-
Allow for Controlling Software Quality (Coupling, Separation of Concerns, etc.)
-
Sometimes, the Best Way to Find a Suitable Library Is to Write the Software Yourself; This Process Can Help Discover Other Programs, Making Self-Implementation a Valuable Library Search Strategy
Of course this approach comes with drawbacks, too:
-
Shouldering the Full Maintenance Burden
-
Likely Repeating Mistakes Already Solved in Established Libraries
A hidden Trade-Off: If a better library is found after self-implementing, discipline is required to weigh the benefits of replacing your implementation vs. maintaining control. This is pretty difficult for humans as it seems to be psychologically hard to delete code.
A Better Alternative: Wrapping
To maintain control while not wasting time and energy, consider the following strategy for external libraries:
-
Pin External Libraries by Default: Utilize features in languages like Rust, JS, or TypeScript; otherwise, leverage tools like Nix or Git.
-
Wrap External Libraries and Shape Their API Around Your Domain Problem:
-
Facilitates Dependency Swapping
-
Enables Partial or Total Replacement of Your Implementation with the External Library
-
Simplifies Comparison and Switching Between Alternatives (a poorly adaptable library may indicate it doesn’t meet your needs)
-
-
Dont wait until you find the perfect library. Start writing your own. When you find a library that suits your needs later, use your library as the API for the wrapper
Mitigating Risks: This approach addresses the challenges outlined earlier by providing a layer of control and flexibility, making the integration of external libraries more manageable.
Conclusion
Understanding the problem domain is invaluable in software development. Sometimes, "reinventing the wheel" can be surprisingly beneficial, leading to deeper insights and more tailored solutions.
Couldn’t find the perfect library for your project? Share your software development challenges with us and receive a free consultation to discuss possible solutions.