When I started my first job as a developer, a childhood friend of mine was my mentor. He taught me many things, such as rubber duck debugging and how to structure my code better in an app at scale.
One of the things he taught me about code structure was always to encapsulate third-party code.
I have to be honest, I hated it at first, it was annoying, and I felt like I was passing props through a wrapper for no good reason.
Then the reason slapped me in the face.
I had to change the whole library I was using because as we dug deeper into the feature I was developing, we discovered it wouldn't work for us. So I would have to replace the external library with a different one that better fit our needs.
Now imagine you've used this library all over your stack. Congrats, you've just given yourself a headache.
Well, maybe not. If you encapsulated that library – just like my mentor told me to do – you only have to change the code in one place. Yes, sometimes the props might be radically different, but you can often use your encapsulating wrapper to "translate" the props to a format that fits the new library.
Since then, I've used this pattern for all external code, from SDKs to UI libraries, and it's saved me days of work during refactors. It also allows me to be more fast and loose when I try out external libraries.
For example, in the last year, I've:
- swapped out one UI library for another
- implemented the same authentication feature using four different services (you can read about that in my next blog post)
I wouldn't say swapping the UI library was a breeze; there were a lot of props that didn't translate from one to the other, but it was still easier than if I hadn't encapsulated it. As for the authentication service, the encapsulation saved me a lot of time and allowed me to give all four a fair chance with relatively little effort on my part.
I find that encapsulating SDKs and helper functions is the most effective. They're also the easiest to make universal.
To effectively encapsulate external code, think about what you want to accomplish more than how the external library wants you to achieve it. That puts the focus on your solution and decreases external influence over how you write your code. As a result, it will be easier to replace that library if you need to.
I encourage you to start using this pattern in your code. It will save you a lot of time during refactors and make your code look a lot cleaner.