Depending on the ecosystem you are working in, there can be a vast sea of wonderful (and not so great) third party packages available to you via package managers like npm
and pip
. This can be a great boon to a developers workflow by helping avoid "re-inventing the wheel", and instead be relentlessly resourceful. With great power comes great responsibility though, and we should never be too quick to adopt third party dependencies without proper vetting, even if the package is very well known.
This guide will aim to help you evaluate a third party package, and ultimately make the call for you, your team, and your company.
Things to consider before adopting:
Features
This is one of the main things usually considered when debating whether or not to use a package; what does it do? But we sometimes don't ask enough about the feature-set of packages, and we should also ask:
- Does this package only solve our use case? Or does the package also contain much more?
- If it does contain more, do you need it?
- Does it unlock new possibilities in the future?
Stability/Momentum
With package managers being so commonplace in today's development ecosystem we can access many libraries very easily without much insight into the stability of the project. A package on it's face can seem really powerful or useful, but at it's core be really unstable and error prone, consider:
- Does the project have many logged issues relative to it's popularity and size? (ie. GitHub issues)
- How often are new versions released? How are releases handled (backwards-compatibility, deprecation handling)?
- Are there tests for the project? What kind of coverage?
- Does the package deal with a crucial component within the system?
Community
The community around a particular project is easy to look past in most cases, but this can come back to bite you if the community is poor. There are few things to consider when trying to evaluate whether there is strong community around a project:
- What outlets does the package have to report issues/bugs? (ie. GitHub issues, forum, Discord, etc)
- Do issues stick around for a long time?
- How popular is the package? How many contributors are there?
- Is there a risk of churn within the community?
Documentation
The quantity and quality of documentation is a really great way to gauge the quality of a project. Having well written, well organized, and thorough documentation can be the difference between the success of a project and the ultimate downfall of it. Writing good documentation takes a great deal of understanding, not only of the project, but it's use case and roadmap. Poor documentation can indicate poor quality in the package.
- Is there documentation available?
- How extensive is the documentation? Are there missing pieces that make it harder to use?
- Is the documentation written and organized well?
- Does the documentation include more than just what the package does? (ie. how the package fits into popular ecosystems, how to test with the package, etc)
Performance
It is sometimes unclear how adding a third party dependency can effect performance of an application, here are some things to consider:
- If the the application is end-user facing, does the new package increase bundle size? If so, how much?
- Is the package bloated and doing more than what is needed, which is costly performance-wise?
- Does the package interact with some other part of the application/system negatively?
Compatibility
A package or library may technically have all the characteristics for a successful integration, but still end up being the incorrect choice for your project. Compatibility has many facets: human, technical, and logistical. And unfortunately, any one of these can mean the adoption of the package is met with lots of friction, or failure. Here are some questions to ask yourself:
- Does the package fit your teams skillset?
- How does the package fit into the build/deployment/CI/CD pipelines?
- Would adoption of the package require lots of refactoring and/or effort?
- What does the project roadmap look like? Will it change drastically in the future?
Things to consider while adopting:
After deciding to adopt a package, there are certain characteristics of your implementation to consider that can make the adoption and use of the package smoother.
Will this dependency be easy to remove?
Whenever possible the developer should consider how easy it will be to remove code while they are integrating it. This will usually push towards good practices like abstraction/dependency inversion. If you can abstract away the package and dictate the interface for interacting with it, it is easier to move from one package to another, or refactor the use of the package.
What is the true responsibility of this package?
Sometimes you can add a dependency to your project that can do much more than it's primary use case in the project. You should be explicit about the use of the third party package, and it should be clear what it's purpose within the system is. You should know what the interface for it should be, limited to only the projects use case. More explicit interfaces/abstractions around a package can help future readers of our code understand the dependency's purpose, and simplify future refactors.
Hopefully some of these questions have helped increase your confidence in the package you are looking to adopt. If you are questioning anything about a library you want to use, always feel encouraged to spark conversation with your peers. In the end you are responsible for maintaining and working on your system so you should feel comfortable working within it, and part of that is having confidence in the third party packages you use.