What Do You Do When a Package You Depend On Is Abandoned?
What Do You Do When a Package You Depend On Is Abandoned?
Work out whether it is abandoned or just finished. A small library that does one thing correctly and has not changed in two years is not a problem. A framework with open security issues and no response in twelve months is. The test is unpatched risk, not commit frequency.
Every marketing site and product we work on sits on a stack of other people's code, and some of that code stops being maintained. The panic reaction is to rip it out. The lazy reaction is to leave it forever. Both are usually wrong.
Here is the framework we use, and the signals that actually tell you which situation you are in.
How Do You Tell Abandoned From Finished?
Ask whether anything is outstanding. A finished library has no open security advisories, no unanswered breakage reports, and a clear scope it has fully covered. An abandoned one has a queue of problems and nobody working through it.
The OpenSSF Scorecard project turns this into a measurable check. Its Maintained check "determines whether the project is actively maintained", and it says that "if there is at least one commit per week during the previous 90 days, the project receives the highest score." It also counts responsiveness, awarding a partial score where "there is activity on issues from users who are collaborators, members, or owners of the project."
That second half is the part we weigh most heavily. Commits can be cosmetic. A maintainer answering an issue is evidence that somebody is still there. A repository with no commits and no replies for a year is a different object from one with no commits and a maintainer who responds in two days.
What Does an Archived Repository Actually Mean?
It means the door is locked, not that the code is gone. GitHub documents that when a repository is archived, "its issues, pull requests, code, labels, milestones, projects, wiki, releases, commits, tags, branches, reactions, code scanning alerts, comments and permissions become read-only."
Two consequences follow immediately. You cannot file an issue, so there is no channel to report a vulnerability through, and nobody else can either. And "contributors with access to the repository can only fork or star your project", which means forking is now the only path to a fix.
Archiving is also reversible, since a maintainer "must unarchive the repository first" to make changes. So an archived repository is a strong signal rather than a permanent verdict. Scorecard treats it as the worst case regardless: "if the project is archived, it receives the lowest score."
Is a Deprecation Notice the Same Thing?
No, and the difference matters. npm documents that "deprecating a package or version will print a message to the terminal when a user installs it", and that for a whole package "a deprecation message will also be displayed on the package page." The code keeps working.
Deprecation is deliberately the gentle option. npm's own guidance is that "we strongly recommend deprecating packages or package versions instead of unpublishing them", because "unpublishing removes a package from the registry entirely, meaning anyone who relied on it will no longer be able to use it, with no warning."
So a deprecation warning in your install log is a maintainer being responsible, not an emergency. Read the message. Often it names the replacement, which turns a vague worry into a concrete migration task.
What Is the Actual Risk You Are Carrying?
An unfixable vulnerability, and nothing else. Abandoned code does not rot on its own. It becomes dangerous when a flaw is found in it and there is nobody to ship a patch, or when the platform underneath it moves and the package cannot follow.
Scorecard frames the vulnerability side directly, checking "whether the project has open, unfixed vulnerabilities in its own codebase or its dependencies using the OSV service", and noting that "an open vulnerability is readily exploited by attackers and should be fixed as soon as possible."
Weigh that by exposure rather than by feeling. A build time utility that never runs in a browser or on a server carries far less risk than a library parsing user input in production. We would tolerate an unmaintained build tool for years and replace an unmaintained input parser immediately.
What Are Your Four Options?
Leave it, pin it, fork it, or replace it. Those are the only four, and picking between them is mostly about how much of the package you actually use.
| Option | Use when | Real cost |
|---|---|---|
| Leave it | Small scope, no open advisories, not in the request path | Ongoing review, near zero |
| Pin and vendor | You need it stable and the registry is the only risk | You own updates forever |
| Fork | Deep integration, you use most of it, a fix is needed | Maintenance, permanently |
| Replace | You use a fraction of it, or an alternative is healthy | One migration, then nothing |
The option teams reach for too readily is forking. Forking is not a fix, it is a transfer of ownership. You now maintain a library, and on a small team that library will be maintained by exactly one person until they leave.
When Is Writing It Yourself the Right Answer?
When you use a small fraction of a large package. If you pulled in a date library for two functions, or a utility collection for one helper, the honest migration is to write those functions and delete the dependency. It usually takes an afternoon and removes the problem permanently.
The test is how much of the surface you actually call. Grep your codebase for the import and count the distinct functions. Teams are routinely surprised to find that a package they were nervous about removing is used in three places for one thing.
Do not do this with anything involving cryptography, date and time zone handling at full generality, parsing untrusted input, or accessibility behaviour. Those are the places where the library's accumulated edge cases are the entire value, and your afternoon reimplementation will be subtly wrong.
How Do You Avoid Getting Here Again?
Check maintenance before you adopt, not after. The question to ask at install time is not "does this work" but "who fixes this when it breaks". A package with one maintainer, no funding, and no recent responses is a decision you are making about your own future workload.
Automate the ongoing part. Scorecard's Dependency-Update-Tool check looks for "Dependabot or Renovate bot", noting that "out-of-date dependencies make a project vulnerable to known flaws and prone to attacks." Either tool will tell you about movement, and silence from one of them over months is itself a signal.
Keep the dependency count low as a policy rather than as an aspiration. Every package is a relationship with a stranger's availability. We wrote about the maintenance side of this in our piece on dependency updates on a marketing site.
What Should You Do in the First Hour?
Establish whether anything is actually exposed. Run your package manager's audit command, check whether the package appears in advisories, and work out whether it executes at build time or at runtime. That triage takes minutes and decides everything that follows.
Then look for a successor rather than assuming there is none. Abandoned packages with real users usually acquire a maintained fork, and the README, the issues, or the deprecation message often names it. A community fork with active maintainers is a much better destination than your own.
Write down what you found, including the decision to do nothing. A dated note saying "reviewed, build time only, no advisories, revisit in six months" is the difference between a considered position and an oversight.
How Do You Explain This to a Client or a Board?
In terms of exposure and cost, not in terms of commit history. "This library has not been updated in two years" sounds alarming and means very little. "This library parses uploaded files, has an open advisory, and nobody has replied to it since March" is a decision anyone can make.
Be equally clear when the answer is to wait. A lot of security theatre comes from teams feeling they must act on every scanner warning. Saying "we looked at this, here is why it is not urgent, here is when we will look again" is a stronger position than a rushed migration.
If you have a stack with a few of these sitting in it and you want help working out which ones genuinely matter, we are happy to go through them with you. Find us at phoenix.studio.
Want a site that performs like this?
Tell us about your project. We will come back with a clear next step, no pressure.
This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.
Have a project like this?
Tell us where you want to go. We'll tell you how we'd get you there.