Sometimes, despite your best efforts and despite following the documentation, the third-party library you chose for a task just won’t cooperate. Maybe it crashes, or maybe it produces the wrong output, or maybe you didn’t check the license up-front and you’re just now finding out you can’t use that library. What can you do?
An ounce of prevention
Before you run into this problem of the failing library, one of the best ways to defend against unpredicted shortcomings in external libraries is to write your own abstraction layer around it. That way, if you do need to swap out the library, you can only make small changes to your wrapper instead of doing a search-and-replace across your whole application.
Is it always appropriate to wrap every third-party library? No. For example, if you need to calculate a particular type of checksum in only one spot in your application, you probably don’t need to abstract that library. Likewise, most web applications wouldn’t gain anything by abstracting jQuery or Zepto — it is assumed that those libraries are a hard dependency in the app, like Rails might be on a backend project.
The intuition of when wrapping a library is appropriate will come with time and experience; but as a rule of thumb, the more places you call that library in your application, the more appropriate it is to abstract away the library’s API.
Find an alternative, equivalent library
Most libraries out there have at least a couple alternative implementations from different parties. Try searching for jquery calendar plugin, for instance. The current top result on Google is a list of 30 different calendar implementations.
If you’re on a spike and figuring out which library to use for a particular piece of functionality, swapping out a library is usually easy and obvious. However, if much of your application already depends on a particular library, swapping out that library may potentially be very painful if you haven’t already written an abstraction layer. And if you don’t yet know which alternative library is most appropriate, then reimplementing the internals of the wrapper a couple times may very well be less painful than going through multiple iterations of search-and-replace throughout your entire application.
Implement the library’s functionality yourself
Reimplementing a library yourself can be very expensive, depending on the library. However, you gain the advantage of having a library that does exactly what you need. And if your client agrees to it, you can even consider releasing your implementation into the wild as another open-source solution.
The middle ground: find a lower-level library
If you do need to reimplement a library, you don’t necessarily need to rewrite the whole implementation from scratch. The trick here is finding an appropriate lower-level library.
Here are a couple examples of what I mean by utilizing a lower-level library:
- You are using a framework that generates sprite sheets from separate images and appropriate CSS to use those sprite sheets, but it doesn’t update the CSS output, even when you force it to recompile. Drop down to a tool like sprite-factory where you precisely control the generated output as a function of sprite position and sprite sheet dimensions, etc.
It’s easy to look at those examples and say “Of course! I wouldn’t dream of implementing a way to generate sprite sheets without using an existing library.” However, it’s also very easy to end up writing large features from scratch without considering existing libraries that don’t completely solve your problem but only get you partway there.
Stay on your toes when it comes to integrating with other libraries. Working around an occasional shortcoming is well within “normal” usage of a third-party library, but if that library regularly gets in your way, hopefully you don’t find yourself completely locked in to that library.