Open-Source software brings great opportunities through a huge ecosystem of reusable packages. The NPM ecosystem grows by millions of packages each year. With so many packages, there is one for everything! There are central server packages like
express, famous UI frameworks like
react, widely used build tools like
@babel/core, or helpful utilities like
lodash. But there are also very specific packages solving niche problems, like a video container format writer based on JSX or an xkcd API client. But not every package is a good pick, often they turn out as a bad choice later on. To avoid regrets when choosing Open-Source dependencies, here are some points to consider.
When choosing packages, we often check whether it fulfills our requirements. Can I use it to solve my problem? Does it match my architecture? These are the most obvious questions, but not the only ones you should ask yourself. Most of the time, choosing a package is a long-term commitment. For that, factors like quality, maintenance, and security are important. Do bugs in the package get fixed? Does the package evolve and accept new features? Will the package be updated to newer versions of the platform? Are security issues handled? Do you trust the maintainers? A package that isn’t maintained can either break your app later on or block you from upgrading dependencies and resolving security issues.
What to look out for?
These are the indicators I personally use when choosing a new package. This is written from the perspective of a TypeScript developer and the NPM ecosystem, but can also be applied to other ecosystems like Maven, Nuget, or Docker. I assume that you first checked that the package is really what you are looking for and fulfills your requirements. Afterwards you can do a deeper assessment of the package.
Package usage is a great indicator. Nothing is better than swarm intelligence. You can do a quick check: How many weekly downloads does the packages have on NPM? Target would be hundreds of thousands or millions of downloads per week. How many stars does the package have on GitHub? Best would be something in the hundreds or thousands of stars, if it’s used a lot it’s probably a good choice. If it’s less, then the package is probably not widely used and it’s questionable whether you can rely on it.
How many issues and PRs does the package have on GitHub? Why are issues and PRs important? They show that and how others are using the package. A lot of issues don’t have to be bad. As long as there are active discussions and the maintainers are participating in it, everything is fine. Do the issues and PRs get handled? You should only use a package if it’s still under active development. If the latest PRs are open for months without a reaction from the maintainer, then it probably isn’t. When was the last commit? How often is someone committing to the repository? Was it in the last year, or in the last two years? If it’s longer ago, it may be problematic. But it depends — maybe there was no reason to update the package. One example is the
cross-env package, the maintainer decided that the package is feature complete and only plans to perform maintenance in the future, if required. Packages don’t go bad if they aren’t updated, or updated often, or just don’t receive new features. However, maintainers should still react on critical or security issues.
When was the last release? That is also a good question to ask. If it’s some years ago, it’s not a good sign. You should prefer projects with regular releases, to be sure that potential issues are fixed and released. But you should also take a look whether there are outstanding changes. If there are too many, or the project is undergoing a larger refactoring, you should ask yourself whether it’s the right time to adopt the project. Will it continue to work as before once the next release is done? Maybe there are better alternatives…
How much support do you get while working with the package? Does the package provide getting started guides, examples, API docs, release notes, and other resources? This is a question that is hard to answer upfront. While you can look for availability, you only know about the quality once you dive into the resources. Here it’s best to give the package a test run, before making a final decision whether it should be used or not. Before that, you should avoid making commitments like “feature
X has to be developed using library
Y”. You can also check whether there is a community around the package: Do you find answers on StackOverflow or GitHub discussions? Are there any external blog posts?
If you are using TypeScript like me, the availability of typings is important. Does the package have types built-in, or at least separate typings from DefinitelyTyped? You can easily check the availability of typings on NPM. There is either a
TS (for built-in typings) or
DT (for DefinitelyTyped) icon next to the package title at the top of the page. If no typings are available it will be difficult to use the package. You still have the option to write your own typings locally, or even contribute them to DefinitelyTyped. But that requires expertise with writing typings and sufficient knowledge about the package itself. Here you should ask yourself, is it really worth it? Are there any alternative packages that have typings available?
Security is an ever growing topic, also when choosing new packages. There are different security aspects that you can take into account. It starts with downloading the package. As NPM already executes
postinstall scripts from the package, you should ask yourself, ”is the package trustworthy?” before installing the package. You have to trust the package authors; do they take their work serious? Are they protecting their accounts correctly? There was a lot of news about package takeover attacks caused by poorly protected accounts, causing a lot of trouble for package users. However, this advice isn’t really useful. You can’t see whether the maintainer is doing that. But what you can see is, how the maintainer is reacting to security issues in his project. Does the maintainer react on security issues at all? Are they handled quickly? What about security issues in dependencies? Are the dependencies kept up-2-date? Are old versions of indirect dependencies blocking you from migrating to newer versions? Always remind yourself that you not only add a direct dependency, but also all indirect dependencies. If you take your work (too) serious, the same questions should be applied for them. Especially in the NPM ecosystem, where you have a lot of dependencies, this can escalate in a lot of work! Here you can come back to the initial question about security: Do you trust the package authors? If they use a similar approach and already checked all their dependencies, you are good to go.
Maintainers & Contributors
The most important topic are the maintainers and contributors. How many contributors does the project have, or is it just maintained by a single person? Is a company backing the project, or even a greater community? Is the project open for external contributions? Take a look at the maintainers of the project on GitHub, how many are there? Does the project belong to a company, or are they from multiple organizations? Are there people contributing to the project that aren’t maintainers?
If you are working with a package that only has a single maintainer that isn’t accepting outside contributions, then you are going to have a hard time. Or sometimes projects aren’t designed for external use at all. What if you want to contribute changes to the project? Investing time into contributions that will not be accepted because the project isn’t maintained is sad. If you aren’t sure whether the maintainer is actively working on the project and is accepting PRs, it’s better to save your time.
What if the maintainer is not able to sustain the project anymore? Maybe their life has changed and they have to take care about more important things? Projects with a single, or very few maintainers can be problematic. Recent events like the Log4Shell vulnerability show what can happen if popular projects are only maintained by a small group of people. Other maintainers are giving up their projects because they don’t receive enough compensation to keep the projects alive. Such support is required to keep projects sustainable. Even projects maintained by companies aren’t save from strategy shifts or budget cuts either. Ideally, the project is maintained and organized by multiple organizations, like projects from the CNCF.
Pet or hobby projects from your colleagues or yourself aren’t the best idea either. They can be problematic from a legal perspective. And what happens if the employee leaves the company? Is the project still maintained or is the company able to maintain it? Probably not, therefore you should avoid mixing such projects with your professional work.
There are even more obvious warning signs that you should take into account. If a repository is archived on GitHub, you better look for another package. Sometimes the repository isn’t archived yet, but the community is working on a successor of the project with similar features. Most of the time you are better off to directly start with the new project. That saves you from migrating later. Issues with tiles like “is this project dead?” are a big warning sign, too — if people start to question it, then it probably is 😉.
The next time you choose a new dependency, keep these things in mind. There is still not guarantee that packages won’t change for the worse. But the chances that you don’t regret your choice later are higher. As long as it isn’t a central package, it’s often possible to replace it with another one, the choice is wide!