the world contains an absurd amount of abandoned code
a short look at what happens to software after people stop maintaining it, using three real pieces of source code that are still sitting online.
There is an enormous amount of software out there, which still exists, but is essentially dead.
In 2025, GitHub announced that it had 630 million repositories, with 395 million of those being public. the fact that 395 million are public doesn’t necessarily mean they’re abandoned. surprisingly, “abandoned” is very difficult to define. A 2020 study of 2,927 active open-source projects showed that 16 percent of the projects stopped being maintained after only 1 year.
what’s also interesting about dead software is that it does not go away. it remains where it is.
1. Atom
Atom is probably the most clear-cut example.
the developer @ GitHub created the Atom editor and released it in 2014. this led to hundreds of thousands of commits; the developers then decided to stop development. today, the main Atom/Atom repository includes over 38 thousand commits. as well as a large banner across the top of the page indicating that the repository has been archived. the entire repository is now read-only.
despite this, the source for everything is still present. there are over 1500 lines of JavaScript in src/Atom-environment.js. you could browse through the class that created the editor’s global Atom environment, read comments written by developers for future maintainers, look through bug reports, or review thousands of past pull requests. unfortunately, there are no longer going to be any future maintainers. fig. 1 — part of Atom-environment.js preserved in the archived Atom repository.
2. Request
then there is Request, a Node.js HTTP library.
its README now starts with only one word: deprecated!
on February 11th, 2020, the project was fully deprecated. however, npm still lists more than 53 thousand packages as dependents of Request. its repository contains more than 2000 commits, plus years worth of issues, test cases, documentation, etc., and the actual implementation of its HTTP client.
this shows that code can be abandoned without losing relevance. somewhere today, old production software is likely making calls to a function from a library that has had no updates since its maintainers explicitly stated that “no new changes would occur here”, six years ago. fig. 2 — the Request constructor inside Request/Request.js.
3. AngularJS
AngularJS is different because it wasn’t some small side project. Google released it and as such an enormous community developed around it. official support for AngularJS officially ended in January of 2022. the GitHub repository was finally archived in April of 2024. it contained more than 9000 commits. src/ng/rootscope.js was one section of the framework, which included the original implementation of $watch, $digest, scopes, along with comments explaining why a particular decision was made at least several years ago. although the framework is effectively dead as far as maintenance goes, the logic behind it isn’t. fig. 3 — AngularJS's $watch implementation in the archived source tree.
4. the graveyard still runs
there is a second reason why we cannot describe the foregoing repositories as “dead.”
some are still alive.
event-stream, a package from npm for dealing with Node.js streams, has been around since approximately 2016. its last major update occurred at that time. according to npm’s current statistics (as of this writing), over five million people download it each week. there appears to be a contradiction here; a software program can effectively stand still while millions of computers continue to pull down copies of it. the developer may have moved on. the source tree for the software may now be silent, yet the code will continue to propagate through dependency chains for many years.
this type of abandoned software is likely one-of-a-kind in terms of what constitutes abandonment. it is not a physical building standing idle in an empty field, but rather a building (in this case a piece of software) that provides structural support to newer buildings (software).
event-stream also has an unusual background. in August 2018, Dominic Tarr, who created event-stream, stopped being actively involved in maintaining it. he gave another developer named right9ctrl permission to take over maintenance of the package. eventually, he allowed him to publish updates to the package. in his first update, right9ctrl added a new package named flatmap-stream as a dependency to event-stream. however, hidden within the published version of event-stream was malicious code. this code was quite unique. it would determine if event-stream was part of a build process for a product named Copay – a cryptocurrency wallet – and if so, identify all Copay products which contained large quantities of either Bitcoin or Bitcoin Cash. shortly thereafter, npm confirmed that the malicious code had actually found its way into final releases of the Copay wallets.
the manner in which the attack began is worthy of note. rather than discovering some previously unknown vulnerability in Node.js, the attackers successfully requested the permissions to manage an older project which had lost interest by its creator.
5. dependency graphs have memory
this also means that simply viewing a repository alone provides an inaccurate representation of where software ends up once it has been retired or abandoned.
most developers do not go out of their way to download event-stream.
another piece of software uses it.
or another piece of software uses something that in turn uses it.
eventually, somewhere within a dependency chain there will be a reference back to code developed many years prior by someone who may not even be using it anymore with regard to a project they last used.
the dependency manager does not care about any of this history.
it only cares about the package name and version number.
thus older software becomes buried as it moves further down into a dependency tree; the less likely the developer(s) who end up executing that software are to realize it is being executed.
this produces a peculiar type of technical sedimentation.
new applications are built upon libraries, these libraries are built upon additional libraries, etc., many of which were originally written for previous versions of programming languages and/or operating systems than that of the newly created application itself.
you can delete your local copy of the project.
you can cease responding to bug reports/requests for assistance.
you can write "DEPRECATED" across the README file.
none of the above will automatically cause the code to be removed from everyone else's dependency graph.
in my opinion this is one major distinction between a physical ruin and a software ruin.
nobody accidentally builds a new apartment building on top of an abandoned factory because their package manager is automatically importing the original factory.
software continues to do this all day long.
6. software archaeology
this seems strange to me.
we typically think of abandoned items as physical: buildings, factories, ships, towns.
software creates ruin too, however unlike other types of ruin software does not rot like buildings do. a repository can simply stop working on some normal day and be frozen into nearly perfect preservation from that moment forward: every variable name, argument, TODO, failed experiment, issue, commit message, etc.
GitHub has actually taken this concept literally.
in 2020, it put a 21 terabyte snapshot of public repositories onto 186 reels of archival film inside a former coal mine in Svalbard for purposes of preserving the code for approximately 1000 years.
we are generating so much code that we are creating archaeology prior to the end of our civilization.
references
- GitHub, Octoverse 2025.
- Coelho et al., is this GitHub project maintained? (2020)
Atom/Atom, GitHubRequest/Request, GitHub & npmangular/angular.js, GitHub & AngularJS documentation- GitHub Archive Program, arctic code vault.
comments