During one of our weekly cross-project tech lead meetings, someone asked about recommendations regarding adding a library to a project. It’s such a common thing in software development, but it can be more a more complicated topic than it might first appear. It was a fun discussion, and out of it came some pretty useful points to consider when deciding whether to add a dependency on a library, picking which library to meet a need, and how to go about integrating it.
1. Is this library worth it?
Dependencies are a liability. Updates can break backward compatibility, projects can become unmaintained, and third-party packages have a higher barrier to change than your own code.
2. Is this part of your project’s core domain?
If the need you’re looking to fill with a library is entangled closely enough with your project’s reason for being, a library may not be the best choice. Unless it’s a perfect fit for your project’s needs, it can become a barrier to iteration at the heart of your project.
You may want to insulate most of your codebase from using it directly. Or you could copy it into your project and take ownership of adapting it to your needs and maintaining it as part of your project. I like to adapt the notions of [core, supporting, and generic subdomains](https://blog.jonathanoliver.com/ddd-strategic-design-core-supporting-and-generic-subdomains/) as a useful framing for this.
3. What’s your exit strategy?
In case the library doesn’t work out long-term or you outgrow it, what actions can you take to insulate yourself from future pain? Consider defining a targeted abstraction for your exact need, and use the library to help implement that — if you can.
Some libraries/needs are too broad, and by adopting the library, you’re making a long-term commitment. Make sure you walk into that relationship thoughtfully!
4. What does it do, and why?
Adding a dependency on a library means adopting code and ideas from another person or team. Learn about it! What’s the rationale behind it? What set of capabilities does it offer, and what secondary or tertiary features may become relevant or useful in the future? [Seek to understand](https://spin.atomicobject.com/2020/11/30/unfamiliar-code-understand/) the library you may adopt and how best to use it.
5. What’s its outlook?
How confident are you that this library is well maintained and well used (enough to surface bugs)? Does it have a future outlook long-lived enough that it’ll be a good “partner” to your software over the course of its lifetime? Bonus points if the maintainers are depending on it to run a business. Extra bonus points if there’s a community beyond that business!
6. What are the second-order effects?
It’s important that the library doesn’t just solve the immediate problem, but that it aligns reasonably with your application architecture, coding practices, testing methodologies, and more.
How well will a set of different library options harmonize with the rest of your codebase? How might you update your own code to harmonize with a library that you’ll be using heavily? What opportunities might exist to leverage capabilities in a new library to multiply out other capabilities of your system?
I hope these questions help with thinking through the trade-offs of adding your next dependency! Are there any important considerations we missed?