Avoid forking dependencies

A common pattern is to fork a dependency to make a minor change, this should be a last resort, I will explain why

Here is a pattern I’ve seen all too often. A well meaning developer spots a dependency that with a small tweak would be perfect for their project. They fork said dependency, make a small change and get on with their day.

In the moment, this is incredible, you get the benefit of someone else’s work, you can customise it for your client, and you can ship it and move on.

The problem is the moving on bit. By forking a dependency without the intention of merging it back in, you’re signing up to supporting it for the life of any projects that need it.

We often take on work started by another team. It is common to find the main codebase at @client/awesome-code, but dependencies are are found at @old-agency/good-idea-at-the-time. Worse still, @one-developer/who-used-to-work-at-old-agency/questionable-idea-at-the-time.

In this article I will go from the worst case scenario to the “best” case, and talk about why you should still avoid it.

Solo developer accounts

A single developer should never own a dependency that they don’t intend on supporting. If you inherit a codebase with dependencies that are forks owned by a single person, the first thing I would suggest is moving that dependency to a new account. Ideally, owned by the client, but anything with more the one person owning it is better than its current state.

If that developer decides to tidy up their NPM account (Why did you pick NPM Toby? Did you have to spend time today unpicking this very issue? How strange!) and removing some fork of some thing they haven’t looked at in years, suddenly your client’s application won’t build.

If you have a good way of explaining to a client that they’ve had to pay you money to fix this in-the-weeds issue in a way that doesn’t make you sound like the caricature of a tradesperson sucking their teeth before telling you your flux-melter-giblet needs replacing then I’d love to hear it! No one should have to pay off this type of technical debt.

Old agency accounts

At least with an agency owning the dependency, there is more of a chance of contingency, yet, it is my experience that even with @old-agency in the dependency title, finding someone who actually wants to take ownership of that, has the appropriate context, and the approval of their management to help make changes or hand something over is, well, challenging!

Again, I would suggest you want to take this work and move it over to the client, or at least your own agency account. This again is to mitigate against someone changing something that is outside of your control.

Client owning the dependency

If the dependencies were over at @client/good-idea-at-the-time then at least the new agency has a fighting chance. Even if they were, this is still an antipattern.

The dependency is frozen in time, with no security, performance, or sub-dependency updates. This will come back to bite you in one form or another.

You’ve built on open source work without contributing back. Ethics aside, you may find yourself violating a license used as part of the original work. Licensing software is a tricky subject and not something you should get involved in lightly.

Documentation could be out of date. Depending on the changes made, the forked project’s README and other documentation could be misleading. Search results will show the original project, which may have documentation based on newer versions of the project.

You’ve increased the amount of projects you or your team have to manage. Instead of allowing the wider community to maintain the original package, you now have to do the work of that community if you’d like to keep up with improvements.

How to avoid owning your own dependencies

I started this article by saying;

A well meaning developer spots a dependency that with a small tweak would be perfect for their project. They fork said dependency, make a small change and get on with their day.

So, what should they have done instead? There are a couple options.

If the needs of the project are not served by a community dependency, then consider building this yourself. As it stands you only have one project’s worth of use-case, so you should not jump into making your own package at this point. Add it to the main application’s codebase.

Consider submitting a patch to the original package, dedicating time to making that package better, and as a byproduct, suiting your needs better is a more pragmatic use of time.


Recent posts View all

Ruby

The best way to test model scopes in Rails

Learn about Rails scopes and how to best test them with both Rspec and Minitest

Ruby

Finding out what called a Ruby method

A quick way to understand what is calling your code using the caller method