When Good Dependencies Go Bad: Axe, Absorb, or Adopt
Open source software is a thing of beauty. Hours of debugging, testing, fixing, and care have gone into writing code so you don’t have to. It’s incredible to think of the time saved thanks to the collaboration of strangers. Of course, every silver lining has a dark cloud.
Libraries disappear. They get abandoned. They die on the vine. So, what can you do about it? You can axe, absorb, or adopt the dependencies which have gone bad.
The first action you can take when a dependency rots away is to simply get rid of it, either by removing the feature it supports or rewriting it internally.
For instance, if an SDK for an API disappears you can just do the HTTP requests yourself with something like cURL. The amount of work involved will vary by the size of the dependency you’re replacing and the portion of it you use. An SDK will often contain code for reaching dozens of endpoints, but you only use one or two. Axing the dependency means you can rewrite the tiny portion of the project which you actually use.
In some cases, the library supports a feature which isn’t critical to your application and can be axed entirely without any replacement. This is common with libraries providing small UI flourishes and transitions which are nice, but far from necessary.
- Quick and easy for small dependencies with light or noncritical usage
- Fewer dependencies reduces reliance on those outside the organization
- Difficult for large, deeply-entrenched dependencies
- Takes time to rewrite the portion you use
- Feature loss
The second way of dealing with the loss of a dependency is to copy its code into your codebase and make it your own.
Provided the license allows you to do so, absorbing the project can be an attractive option—particularly when it’s a manageable size. You may have to massage it to fit your coding standards, but once it’s in your codebase you are free to do anything you like with it. This includes adding and removing features, removing abstractions to directly fit your usage, and generally treating it like your own code—because it is.
Of course, you miss out on the value added by those outside the organization—no more free bugfixes and enhancements. In exchange though, you get to have full control over the code.
- No longer at the mercy of someone else for changes or bugfixes
- Complete control to change code and customize to your needs
- No need to worry about the concerns of anyone outside your organization
- The license may not allow it
- No contributions from people from outside your organization
- Code style may have to be changed or unit tests added to meet your standards
- Inheritance of its dependencies, leading to more direct dependencies
Finally, we have the noble (though often impractical) option of becoming the official maintainer of the project or a fork of it, keeping it open source and available to others.
By doing so you get a bit of notoriety and help out the other users of the dearly departed project. With any luck, users outside your organization will report bugs, submit patches and features, and write documentation. Of course, this route comes with its fair share of headaches as well—c’est la open source.
By going this direction, you sign up for management of a whole project with concerns extending beyond your own usage. Backwards compatibility and genericity become important. People demand things of you.
- Contributing to open source
- Users outside your organization may contribute features and bugfixes
- Overhead of maintaining an open-source project—updating dependencies, fixing bugs, merging PRs, etc.
- You may have to maintain more features than your company actually uses
When you need to replace a dependency, there is no one-size-fits-all answer. There is no best. There is only what is best for you and your organization. You have to weigh the factors of the dependency’s size, amount of usage, compatibility with your standards, complexity, and value.
Ultimately though, whether you axe, absorb, or adopt the project what is important is that you’ve thought through the pros and cons of each. It’s not always easy, but hopefully this framework simplifies your decision. Good luck out there.