When a whale dies in the open ocean, its carcass sinks to the abyssal floor and becomes an ecosystem. Marine biologists call this a whale fall, and the body sustains life in three overlapping stages: mobile scavengers strip the soft tissue over months, enrichment opportunists colonise the bones and surrounding sediment for years, and chemosynthetic bacteria feed on the skeleton itself for decades, converting the lipids stored in bone into energy that supports entire communities of specialised organisms. A single whale fall can sustain life on an otherwise barren ocean floor for fifty years.

Michael Winser mentioned whale fall offhand while we were talking about what happens to the dependency graphs of abandoned projects, and it won’t leave my head.

A large open source project goes unmaintained. Maybe the maintainer burns out, maybe the company behind it pivots. The project stops getting updates but doesn’t disappear. It sits on GitHub accumulating issues, its last commit receding further into the past, and somebody forks it to start merging the most urgent patches. If the project was popular enough, multiple forks appear, competing for users the way hagfish compete for blubber, though most die quickly and one or two survive on the strength of someone with enough time or institutional support to keep going. OpenOffice became LibreOffice this way, MySQL became MariaDB, Hudson became Jenkins, each a scavenger fork that grew into the canonical replacement through a familiar sequence of fork announcement, migration guide, and “why you should switch” blog posts.

Smaller projects then start extracting specific modules or building tools that target the dead project’s data formats. Google Reader wasn’t open source, but the same thing happened when it shut down: Feedly, Miniflux, FreshRSS, Tiny Tiny RSS, and a dozen others rushed to fill the vacuum, several of them implementing the Google Reader API or the Fever API not because those were good APIs but because years of RSS clients had been built to speak them. The licence didn’t matter. The interfaces were public, other software depended on them, and that was enough.

And then the structural skeleton, the protocols and file formats and API contracts, goes on supporting specialised communities that may not even know where the bones came from. OpenDocument Format has outlasted the OpenOffice community that created it, sustained by document format libraries across dozens of language ecosystems. Docker donated its container runtime and image format to the Open Container Initiative in 2015. The OCI spec now defines how containers work regardless of runtime. Docker’s own dominance faded; the spec didn’t. Tree-sitter was built for Atom, and after GitHub archived Atom it became the syntax engine inside Zed, Neovim, Helix, and most editors shipped in the last few years.

Succession

The pattern I keep noticing with unmaintained libraries is successive recolonisation. A project goes quiet, someone forks it, other projects start depending on the fork, and then that fork maintainer burns out too and the whole cycle repeats at a smaller scale. Each generation of fork is typically smaller than the last, with fewer contributors and a narrower user base, until eventually the idea itself migrates rather than the code. Someone in another language ecosystem looks at the accumulated wreckage and decides to rewrite the concept from scratch, carrying the design forward but leaving the implementation behind.

Sass went through this. The original reference implementation was a Ruby gem. When Ruby’s performance became a bottleneck, LibSass rewrote it in C++, and the sassc gem wrapped that for Ruby users. Then LibSass itself was deprecated in favour of Dart Sass, which is now the canonical implementation. The concept migrated from Ruby to C++ to Dart across a decade, each rewrite benefiting from the accumulated bug reports and design arguments of its predecessors, and at each stage there were wrapper libraries in other ecosystems feeding on the structural skeleton of the Sass language spec. Most people writing Sass today have no idea it started as a Ruby gem.

Successive recolonisation has a nasty failure mode. Edera discovered a differential parsing bug in Rust’s tar-rs library that affected every fork downstream: tar-rs itself, async-tar, tokio-tar, and multiple internal forks maintained by companies like Astral (whose fork ships inside the uv package manager). Coordinated disclosure meant contacting around twenty entities across a fragmented fork graph where three of the four library versions were unmaintained and several maintainers were unreachable. The vulnerability existed because the code had been copied forward through successive forks without anyone re-auditing the PAX header parsing that all of them inherited from the original. The bug had been sitting in the bones the whole time, inherited by every fork. Discovering which forks of a package are affected by an advisory is a problem I’m working on separately, because right now nobody has good tooling for it.

CentOS after the Stream pivot is the same pattern at operating system scale: Rocky Linux and AlmaLinux forked, smaller RHEL-compatible rebuilds appeared in the enrichment layer around them, and the structural skeleton underneath, RPM packaging, systemd conventions, filesystem hierarchy, persisted unchanged regardless of which particular distribution is alive or dead at any given moment.

Licence changes

When a project switches from an open source licence to a source-available one, the scavenger stage triggers almost immediately, often before the change even takes effect. Redis to Valkey, Elasticsearch to OpenSearch, Terraform to OpenTofu, the pattern by now is familiar enough that the community has it down to a routine: rush to fork the last open commit, compete briefly, and consolidate around one or two survivors. The organism isn’t exactly dead in these cases. Redis the product still has revenue and a roadmap. But from the perspective of the open source ecosystem the body of code has stopped accepting outside contributions, and the forks start drifting from the original the way MariaDB drifted from MySQL.

The abstraction layers are the part that lasts. Every project that integrated with the open version faces a choice between following the proprietary version or switching to the fork, and plenty of them just build a compatibility shim instead. Those shims tend to outlast the controversy that created them, feeding quietly on the skeleton of the original API years after the licence debate has cooled off.

Sun Microsystems

Oracle’s acquisition of Sun in 2010 was less a single whale fall than an entire pod dying at sea simultaneously. Java, Solaris, ZFS, DTrace, VirtualBox, NetBeans, GlassFish, Hudson, MySQL, each sank to a separate ocean floor and spawned its own succession. Some produced single dominant forks (Hudson to Jenkins, ZFS to OpenZFS), others scattered into competing lineages (MySQL alone fed MariaDB, Percona, and briefly Drizzle, which itself became a smaller whale fall when it was abandoned), and some bounced between foundations before settling (NetBeans to Apache, GlassFish to Payara and the broader Jakarta EE ecosystem). The structural skeletons underneath all of it, the JVM bytecode format, the ZFS on-disk format, the MySQL wire protocol, are still load-bearing in projects whose developers have never heard of Sun.

Shallow water

Some projects die in shallow water where the carcass gets recycled quickly. Acqui-hires work this way: the company gets absorbed, the code goes proprietary or gets archived, and the knowledge disperses with the people rather than accumulating in a public carcass that others can feed on. Corporate consolidation has a similar effect, because when a large independent project gets folded into a platform company’s proprietary service, the nutrients get recycled in the water column rather than sinking deep enough for succession to happen.

I think the current trend of consolidation under cloud providers is reducing the whale fall rate in open source, and that this has second-order effects on ecosystem diversity that nobody is tracking. You could measure it: look at the fork and dependency graphs of dead projects over time, count how many new projects cite a dead dependency, compare the half-life of a whale fall in npm versus crates versus rubygems. Do some ecosystems have deeper ocean floors, slower decomposition, longer-lasting structural influence? The data exists in package registries and forge APIs, but I haven’t seen anyone ask the question.

An open source ecosystem where every large project is owned by a platform company, maintained indefinitely or quietly absorbed on death, is one where those enrichment and chemosynthetic stages rarely get a chance to develop, and the small specialised organisms that depend on whale falls for food never get a chance to evolve. The healthiest ecosystems have a steady supply of whale falls, which is an odd thing to root for since it means wishing for the death of large projects, except that the deep ocean floor has no other food source.