开源项目“离谱的死亡方式”
创始人
2026-05-22 14:53:03

如今大量被广泛依赖的软件包,其实早已在某种意义上停摆,只是依然通过依赖链持续运转。它们没有统一的死亡时刻,也没有明确的终点,而是在不同条件下逐渐滑向失效状态。

而一个项目之所以会走到这种“仍然存在但已经失去生命力”的状态,原因往往五花八门。下面这些情况,基本覆盖了开源项目如何一步步“消失”的路径。

维护者离开了

“幽灵维护者”

这是最简单、也最常见的一种情况:很多开源项目的最后一次人工提交记录停留在几年前,后来 Issue 不断堆积却无人回应,但仓库又没有被归档,因此不会出现在那些专门筛查“废弃项目”的过滤列表中。

通常情况下,这些项目的维护者们只是转去做别的事情了,而这个项目对他们来说,又没重要到需要正式移交或关闭的程度。当然,同样的“沉默”背后,也可能意味着更极端的情况——甚至包括维护者已经去世,而无论是软件仓库还是包管理平台注册表,都没有办法表达这种状态。

从外部来看,这种项目很难和“维护者只是休了个长假”区分开来。直到无人回复的问题越来越多,沉默才逐渐变得无法忽视。如今 npm 生态中很多高依赖量、却已经“名存实亡”的工具,大多属于这一类。

“企业弃儿项目”

有些项目最初由公司创建并开源,也曾拥有专门团队负责维护。但后来公司战略转向、组织调整,或者经历裁员之后,原团队消失了,而 README 却没人更新。

GitHub 组织页面还挂着公司 Logo,但最后拥有管理员权限的人可能早就离职了,于是公司内部甚至没人知道这个项目依然“属于自己”。

Google 各种著名“墓地项目”算是最典型的例子,但实际上,几乎每一家发展到一定规模的公司,都会留下几个类似的遗弃项目。尤其是那些偏基础设施性质、而不是直接面向用户的项目,往往连正式的弃用公告都没有。

“论文孤儿”

还有一类项目,是研究生为了硕士课题或博士论文而开发的。等学生毕业离开后,项目也随之失去维护。虽然实验室名义上仍拥有仓库,但里面已经没人具备继续维护它所需的上下文知识。

更现实的问题在于:学术体系并不会激励人去维护别人留下的软件。维护旧代码拿不到引用,对评审和晋升也几乎没有帮助,相比之下,发表新的论文显然更重要。因此,科研软件生态里充满了这种“论文还在被引用,但代码早已无法编译”的项目。

“资金断崖”

有些项目依靠资助、基金会拨款,或者限期赞助维持运转。

问题是,这类资金往往本来就有明确结束时间。一旦资金到期,维护者就得回去做真正能养活自己的工作。

于是,一个原本依靠全职投入发展起来的项目,突然只能靠业余时间维护。而对于已经扩张到一定规模的项目来说,“晚上和周末维护”基本等于无人维护。

很多时候,资助方的 Logo 依然会长期留在 README 里,因此外界很容易误以为它依旧是一个健康、持续被赞助的项目。

“被公司挖走”

还有些项目,是因为维护者被公司招募后逐渐停摆。

有时候是劳动合同限制,有时候只是新工作太忙,导致项目自然失去维护。

偶尔也会出现“竞争对手故意挖人”的情况,但更常见的其实并非恶意。例如 Apple 就是一个经典案例:它通常不允许大部分员工继续参与外部开源项目。

因此,一个维护者加入 Apple,往往就意味着他原本的项目默认进入“静默状态”。

理论上,最合理的做法是在入职前完成项目交接,但现实里,几乎没人能及时做到这一点。

“继承僵局”

还有一种情况更加棘手:

原维护者已经失联,但社区里其实有人愿意接手项目。

问题在于,软件包发布权限绑定在一个无人能访问的账号上,而 GitHub 仓库也没有其他管理员。与此同时,包管理平台针对“废弃项目”的处理流程,又通常要求原维护者同意,或者经历漫长的争议处理过程,而没人明确知道该由谁来发起。

Python 的 PEP 541 流程、npm 的争议处理政策,都是专门为这种情况设计的。

但现实是,它们往往耗时长到一个程度:开发者重新 Fork 一个新项目并改名,反而更快。

「CSDN读者专属福利」,免费领 100 小时云算力

进群月月抽显卡、AIPC,好运不停!

咖啡领取地址:https://s.csdn.cn/4nPsOp

维护者其实还在

“项目陷入了停滞期”

从各种指标上看,项目似乎依然活跃。

一些拼写错误修复、依赖升级还会被合并,Issue 下面偶尔也能看到一句“谢谢,我会看看”。但凡是真正需要做设计决策、深入调试的问题,却会无限期挂在那里,因为维护者早已没有精力再认真投入这个项目。

这种状态通常最微妙:项目“看起来”还活着,因此任何提出 Fork 的人,都会被拿近期活动记录反驳;但与此同时,它又始终无法真正推进。

而这种“不死不活”的状态,完全可能持续好几年。

“善意僵尸”

贡献图一片翠绿,但所有提交都是机器人完成的。

Dependabot 自动升级依赖、自动合并规则自动通过 PR、自动化发布流程自动生成版本,如今甚至还有定时运行的 AI Coding Agent,可以在没有任何人类阅读代码的情况下,让项目长期“保持运转”。

于是,所有基于“最近是否有提交”的健康评分系统,都会认为这个项目状态良好。

而这恰恰暴露了“基于活跃度评分”的最大问题:它根本无法判断,背后到底还有没有真正的人类维护者。

“项目管理权之争”

有时,开源软件项目的多个共同维护者之间会彻底闹翻。双方都拥有足够权限阻止对方,但又没有能力单独推进项目,于是整个项目被冻结在中间。

有些项目最终会演变成 Fork,有些则会以其中一方退出收场。但也有很多项目,就这样长期僵在那里。

Issue 区不断涌入用户询问“到底发生了什么”,而他们得到的,往往是两套互相矛盾的说法。

“经验知识流失了”

这种情况下,代码还能运行,测试也全部通过。但真正理解“为什么这样设计”的那个人已经离开了。

剩下的人虽然还能修一些边边角角的小问题,却没人敢碰核心结构,因为没人有信心改动那些真正承重的部分。

于是项目实际上进入了一种“只读模式”:外围补丁还能接受,任何结构性修改都被视为风险过高。

这种情况在数值计算、解析器等领域尤其常见。因为最难的部分,往往是某个人十年前根据一篇论文实现的算法,而他从未真正写过完整文档。

“有毒守门人”

还有一种情况更糟:维护者不仅还在,而且态度极其敌对。

新贡献者第一次提交 PR,往往就会遭遇一次“毁灭性 Code Review”,之后再也不回来。于是项目的“巴士因子(Bus Factor)”始终停留在 1 —— 因为没人愿意和这个人一起维护仓库。

从提交量、关闭 Issue 数等指标来看,项目甚至可能非常“健康”。但等到这个唯一维护者最终停下来的时候,项目就会瞬间变成“幽灵维护者”状态,而且没有任何接班人,因为那些原本可能接手的人,早在很多年前就被赶跑了。

被破坏与被劫持

“维护者被劫持”

有时,代码提交权限或发布权限会落到心怀恶意的人手里。

xz 事件是最复杂、最经典的案例:攻击者花了两年时间,对一个过劳的单人维护者进行社会工程攻击,最终成功成为共同维护者,并在之后发布了带后门的版本。

2018 年的 event-stream 事件则简单得多:原作者把包交给了一个“主动帮忙”的志愿者,而对方随后就在下游依赖里植入了盗取加密钱包的恶意代码。

两起事件有一个共同点:在“被劫持”期间,项目甚至比以前看起来更健康。因为真正积极干活的人,正是那个新的恶意维护者。

“抗议软件”

有时,破坏项目的人甚至就是合法维护者本人。

2022 年,colors 和 faker 的作者故意破坏了自己的包;更早之前,2016 年的 left-pad 则在与 npm 的争议中被作者直接下架。

背后的动机各不相同,但对下游生态造成的影响却是一样的:仓库里的代码,不再是用户以为自己正在运行的那份代码,而且这一切通常毫无预警。

发布流程出“问题”了

“有人维护,但发不了版”

开发仍在继续,修复也已经提交进 Git 仓库,但就是没人能真正发布新版本。

唯一拥有发布权限的账号已经失联、丢失了 2FA 设备,或者属于一家早已不存在的公司。

结果就是,下游用户只能继续使用最后一个已发布版本,而他们真正需要的修复,其实已经静静躺在仓库提交记录里,只是永远无法从软件源安装到。

“无法发布的主分支”

默认分支已经与上一次正式发布版本偏离太远。如果现在直接发布,会对整个生态造成破坏性变更。而没人愿意承担这个责任,于是干脆没人发布。

新贡献者依然不断往 main 分支提交补丁,但用户实际运行的,还是几年前的旧版本。

随着时间推移,两者差距越来越大,最终,“发布一个新版本”本身就变成了一个需要专门立项的大工程,而这个工程永远排不上优先级。

“构建考古学”

已经发布的产物还能运行,但没人知道该怎么重新构建它们。

可能是当年的 CI 服务已经关闭,也可能是依赖的基础镜像被删除,或者某个关键工具版本,只存在于一位维护者已经报废的旧电脑里。

于是,每次想发布新版本之前,都得先“考古”出当年的构建环境。而真正知道环境细节的人,早已经离开项目。

“影子维护”

真正的开发工作,其实发生在公司内部的私有单体仓库里。公开仓库只是偶尔同步一次代码,提交信息通常只有一句简单的 “sync”。

用户在公开仓库提交的 Issue 和 PR 基本不会得到回应,因为那根本不是开发者真正工作的地方。

于是,这个所谓的“开源项目”,实际上已经退化成了闭源项目的一个发布渠道。从外部来看,它和“幽灵维护者”项目几乎没区别,除了偶尔同步代码的那几天。

“被困住的大版本”

项目已经更新到 v4,而且维护得很好。但整个生态还停留在 v1。

因为 v2 曾经是一次彻底重写,大多数用户从那之后就再也没迁移成功。而 v1 又已经很多年没人真正维护。

于是,“这个项目到底死没死”,完全取决于你问的是哪个大版本。

而最讽刺的是,安装量最高的版本,往往恰恰不是维护者真正关注的那个版本。

“注册表孤儿”

软件包还能从注册表正常下载,但它元数据里的源码仓库链接已经 404 了。

仓库可能被删除了、改成私有了、迁移后没更新地址,或者托管平台本身已经关闭。

这就导致没人知道该去哪里提 Issue,也没地方 Fork,更无法验证注册表里的 tarball 是否真的对应某次源码提交。

统计数据显示,大约 1.7% 的 npm 包,以及约 4% 的 Packagist 包,都指向了一个已经不存在的仓库。而其中相当一部分,至今仍在被持续安装。

不可抗力

“被制裁困住”

维护者既有能力,也愿意继续维护项目,但就是无法发布更新。

原因可能是:软件注册表屏蔽了他们所在的司法辖区,或者他们的账号因出口管制被冻结。

过去几年里,npm 和 GitHub 上已经出现过多起类似案例:一些开发者账号被直接暂停。而对于下游用户来说,这种情况和“幽灵维护者”几乎没有区别——项目突然不再更新、没人响应、版本停滞。

唯一的不同是:维护者本人通常还在其他平台上大声解释到底发生了什么。

“下架受害者”

项目因为 DMCA 投诉或商标纠纷,被托管平台或软件注册表移除。youtube-dl 在 2020 年被下架后最终恢复了,但大量更小的项目并没有这么幸运。而且,一个项目最终是否还能继续被安装,和投诉本身是否合理,并没有必然关系。

很多时候,只要包已经被移除,生态就已经断裂了。

世界已经变了

“平台遗弃”

项目被困在一个已经寿终正寝的平台上。例如只能运行在 Python 2 上、依赖一个已经从 CI 镜像中移除的 Node 版本、依赖某个已经被删除的编译器扩展。

理论上这个开源项目可以迁移,但问题在于,把它移植到现代环境里,需要投入大量的工作量,而这些工作量已经超过现存维护者愿意承担的范围。

于是项目就这样停留在过去,而它所依赖的平台,也逐渐从所有现代运行环境中消失。

“传递性死亡”

有时,一个项目本身其实没问题。维护者还在,也愿意继续维护。

但它依赖树中更深层的某个组件——可能是两层、三层以下的依赖——已经通过前面提到的某种方式“死掉”了,而且除非彻底重写,否则根本无法替换。

于是,这个项目也会被连带“拖死”。

最关键的是它自己的仓库里甚至什么都没变。这是整个开源生态最递归、也最可怕的一点: 前面列出的每一种“死亡方式”,其实也都是杀死所有下游依赖项目的方法。

“API 突然终止”

项目封装的外部服务,被所有者撤掉了。在服务层面,最常见的是:某个 API 被关闭,或者价格涨到无法承受。

例如,Twitter 在 2023 年的 API 政策变化,以及 Reddit 后续的收费调整,就一次性“杀死”了整整一代依赖这些平台的客户端库。

而在平台层面,则是浏览器废弃了某个接口,或者操作系统封锁了某项能力。所有基于 NPAPI、Flash 或 Chrome Apps 构建的生态,都属于这种情况。

无论是哪一种,维护者其实都无能为力。因为问题根本不在他们这一侧。

“被时代取代”

开源项目的功能已经不再被需要。原因可能是:它实现的规范已经被替换,或者编程语言本身已经原生支持了同样的能力。

例如:

  • Object.assign 出现后,object-assign 失去意义

  • ES2015 普及后,大量 lodash 单函数包逐渐被淘汰

  • 各种 Promise 和 fetch Polyfill

  • 以及那些用于处理早已没人再生成的数据格式的协议库

于是维护者很自然地停止维护。但与此同时,几十万份锁定文件依然在持续安装这些包。

因为对于大多数人来说:“一个还能正常解析的依赖”,永远不会是优先清理事项。

项目分裂了

“项目 Fork 陷入僵局”

当社区里面存在理念分歧、或者维护者离开时,往往会让项目分裂成多个 Fork,但问题在于:没有任何一个分支可以最终胜出。

于是,下游生态宁愿停留在“原项目分裂前的最后一个版本”,也不愿赌哪个 Fork 能活下来。

结果就是——原项目依然保有巨大的安装量,而真正的开发工作,却已经在其他名字下悄悄进行。最典型的案例就是 io.js 与 Node 最终重新合并了;libav 也最终回归 FFmpeg。但更多的小型分支项目,则永远没有迎来结局。

“许可证变更的后续影响”

有些开源项目修改了许可证,变成非开源软件。随后,社区仍然基于旧许可证 Fork 出一个新项目,但生态并没有真正完成迁移,使用量一直上不来。Terraform / OpenTofu、Redis / Valkey 都面临着类似的困境,而 Elasticsearch 已经比它们更早走上这条路几年。

如今,大量锁定文件依然指向原项目最后一个“真正开源”的版本。可那个已经变成了一个没人维护、却永远停留在那里的固定版本。

“开源核心被掏空”

真正有价值的开发工作,已经转移到商业版本里。开源仓库仍然存在,但更多只是作为“免费版本”保留下来。它依旧会发布新版本,但大多数只是版本号的更新,以及进行一些与付费产品无关的改动。

于是,人们当初采用的那个“开源项目”,实际上已经慢慢变成了另一个规模更小、能力更弱的东西。只是它从来没有改过名字。

相关内容

热门资讯

告别台面茶具水壶堆满,碧云泉T... 家里的台面上,烧水壶占去一角,保温杯排成一列,煮茶器、泡茶壶、公道杯挤在余下的空间里。台面收纳不是简...
绿色黄金:茶叶、帝国与工业化 1 基本信息 作者: [英]艾伦·麦克法兰 (Alan Macfarlane) / [英]艾丽斯·麦...
浙江丽水:荒野古茶变“富民金叶... 将山野中被人遗忘的古茶树重新培育“唤醒”,采摘茶叶制作成各类生态荒野茶上市销售,2025年,浙江省丽...