- Published on
What Replaces Technology — And How to Check Whether Your Stack Sits on That Trajectory
- Authors

- Name
- Youngju Kim
- @fjvbn20031
- Introduction — a post about the pattern, not the list
- The five forces that drive replacement
- How to check whether your stack sits on that trajectory
- Migrate, or wait?
- Finally — how to treat a list like this
- Related reading
- Series
Introduction — a post about the pattern, not the list
The previous three parts covered some thirty projects. The list itself will go stale. What remains is the pattern: what drove the replacements, and how to recognise the same symptoms in your own stack.
One premise, restated. Most of the projects that gave up their place were the right choice in their own time. The forces below generally operate independently of project quality.
The five forces that drive replacement
1. The platform absorbs the feature
The most common one. PhantomJS gave up its place once browsers shipped headless mode; jQuery Mobile did so once CSS and touch events became standards.
This is not failure. Once a tool proves the demand, the platform takes that demand over. Ask whether the gap a tool fills is the kind of gap a standard will eventually close, and you get a rough estimate of that tool's remaining life.
2. Operational burden exceeds the benefit
Kafka removing its ZooKeeper dependency is the archetype. Borrowing a proven external system was a reasonable initial judgement, but running a separate ensemble kept costing.
The signal to watch is clear: the proportion of your time spent operating the accessory rather than the core. When that proportion grows, at some point the core either absorbs the function or strips it out.
3. Maintainer headcount becomes the bottleneck
This is the most repeated reason in this series. The LibSass deprecation notice said honestly that there was not enough engineering bandwidth to keep up with the language; the ingress-nginx retirement notice said one or two people had maintained it in their spare time for years; the Create React App deprecation notice cited the absence of active maintainers.
The risk in a dependency lies not in code quality but in the number of people who can maintain that code. And that number is entirely invisible in star counts and download figures.
4. The license changes
The only axis on which movement happens with no technical reason at all. Stated as facts:
| Project | Before | After | Announced |
|---|---|---|---|
| MongoDB | AGPL v3 | SSPL | 2018-10-16 |
| Elasticsearch, Kibana | Apache 2.0 | Dual SSPL and Elastic License | 2021-01-14 |
| HashiCorp products | MPL 2.0 | BUSL 1.1 | 2023-08-10 |
| Redis | BSD 3-Clause | Dual RSALv2 and SSPLv1 | 2024-03-20 |
The reversals belong here too, for balance. Elastic added AGPL as an option on 29 August 2024, stating that it was adding an option rather than removing anything, and Redis added AGPLv3 from Redis 8 on 1 May 2025.
And the forks that emerged from each change.
| Fork | Original | License | Steward |
|---|---|---|---|
| OpenSearch | Elasticsearch, Kibana | Apache 2.0 | Linux Foundation |
| OpenTofu | Terraform | MPL 2.0 | Linux Foundation |
| Valkey | Redis | BSD | Linux Foundation |
That all three went to a foundation is the heart of this trend. The market's response to a license change was not to move to another company but to create a neutral steward.
I will not speculate about motives here. Each company stated its reasons in its own announcement, and reading them as written is enough. One thing matters to practitioners: a license is a value that can change, and the change is usually not retroactive.
5. The problem definition moves
TSLint was a well-built linter, but the side that designed for a swappable parser lasted longer. rkt was an alternative runtime, but what ultimately survived was not a particular runtime; it was a standard interface.
A problem solved by a specific implementation tends to lose to one solved by an interface. Distinguishing whether a tool defines an interface or is one implementation makes it far easier to guess which side survives five years out.
How to check whether your stack sits on that trajectory
Use verifiable signals, not impressions.
What to check in documentation
- Does official documentation carry a support end date? Languages and frameworks usually do.
- Does the README or site carry a deprecation statement? Bower and Moment.js both discourage new use while the repository stays alive.
- Is a successor project designated? Rome named Biome; Heapster named metrics-server.
- Is an escalation path documented, and has it actually worked recently?
What to check with a command
Repository archive status and last push time are one API call away.
# Archive status and last push time
OWNER_REPO="kubernetes/ingress-nginx"
curl -s -H "Authorization: Bearer ${GITHUB_TOKEN}" \
"https://api.github.com/repos/${OWNER_REPO}" \
| python3 -c "
import sys, json
d = json.load(sys.stdin)
print('archived :', d['archived'])
print('pushed_at :', d['pushed_at'])
print('open_issues:', d['open_issues_count'])
"
More important is how many people hold merge authority. Many contributors but few mergers means those few are your bus factor.
# Distribution of mergers across the last 100 merged PRs
curl -s -H "Authorization: Bearer ${GITHUB_TOKEN}" \
"https://api.github.com/repos/${OWNER_REPO}/pulls?state=closed&per_page=100" \
| python3 -c "
import sys, json, collections
prs = json.load(sys.stdin)
c = collections.Counter(p['merged_by']['login'] for p in prs if p.get('merged_by'))
for who, n in c.most_common(10):
print(f'{n:4d} {who}')
print('distinct mergers:', len(c))
"
What to keep as a list
Recording four values per critical dependency prevents most incidents: the official support end date, repository archive status, the designated successor, and a rough estimate of what moving would cost today.
That last value is the important one. Estimate the exit cost once at adoption time and you can later decide whether to move using numbers rather than feelings.
Migrate, or wait?
Not every deprecation notice demands immediate action. Two axes make the judgement easier.
The first axis is security exposure. If security fixes have stopped and the component is network-exposed, it is top priority. The ingress-nginx statement warning that continuing to use it after retirement leaves users vulnerable to attack is exactly that case. Conversely, a build tool that only runs inside CI has a very different urgency for the same kind of notice.
The second axis is the maturity of the replacement. If a successor is officially designated and migration documentation exists, the cost is predictable. If there are several candidates and none dominant, waiting one more cycle can be the rational choice.
Multiplying the two axes gives this.
- High exposure, clear replacement → migrate now.
- High exposure, unclear replacement → reduce exposure first. Isolate, restrict access, consider commercial extended support.
- Low exposure, clear replacement → fold it into the next major piece of work.
- Low exposure, unclear replacement → put it on the list and check its state each quarter.
And one easily forgotten option. Replacing a maintained tool is also a cost. If a tool like Grunt has a live repository and receives security fixes, there is no reason to move simply because the fashion changed.
Finally — how to treat a list like this
A few rules I kept while writing this series, which may be useful elsewhere on the same subject.
- Do not write that a project with remaining users and maintainers is dead. The fact is usually that it gave up its place or that its use narrowed.
- Do not speculate about why someone stopped. Carry over only what was stated publicly, and cite it.
- If it cannot be verified, leave it out. Impressions are not evidence, and usage trends without a citable source do not get quoted.
- Always record what it left behind. Most projects left something that outlasts their name.
That last rule is why this series exists. Electron, which Atom left behind; the standardisation pressure rkt created; the coordination-service category ZooKeeper defined. Even when a project's name disappears from the list, what that project proved is inside the tools we use today.
The stack you use now will eventually appear on a list like this. That is not a bad thing; it most likely means that tool proved something.
Status information was verified directly on 2026-08-12. Projects sometimes become active again, so check the current state yourself.
Related reading
- Bus factor is the number of people who can decide
- When open source governance breaks
- Open source license shifts 2026
- The reality of the Airflow 2 EOL migration
- Working with legacy code
- Tools: SW Maintenance Checklist · Text Diff Checker · Git Playground
Series
- Build and frontend tooling
- Infrastructure and containers
- Data stores and queues
- Languages, frameworks and runtimes
- What replaces technology (this post)