开源项目“离谱的死亡方式”
在开源世界里“项目死亡”往往并不意味着仓库被删除或代码彻底消失更多时候它只是以各种更隐蔽的方式继续存在没人维护、无法发布、依赖链仍在运行或者只是看起来还活着。这正是 Andrew Nesbitt 长期关注的问题。这位曾任职于 GitHub 和 Tidelift 的软件工程师指出所谓“项目死亡”从来不是单点事件而是一连串结构性失效的结果。来源https://nesbitt.io/2026/05/19/dumb-ways-for-an-open-source-project-to-die.html作者 | Andrew Nesbitt 责编 | 苏宓出品 | CSDNIDCSDNnews如今大量被广泛依赖的软件包其实早已在某种意义上停摆只是依然通过依赖链持续运转。它们没有统一的死亡时刻也没有明确的终点而是在不同条件下逐渐滑向失效状态。而一个项目之所以会走到这种“仍然存在但已经失去生命力”的状态原因往往五花八门。下面这些情况基本覆盖了开源项目如何一步步“消失”的路径。维护者离开了“幽灵维护者”这是最简单、也最常见的一种情况很多开源项目的最后一次人工提交记录停留在几年前后来 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 已经比它们更早走上这条路几年。如今大量锁定文件依然指向原项目最后一个“真正开源”的版本。可那个已经变成了一个没人维护、却永远停留在那里的固定版本。“开源核心被掏空”真正有价值的开发工作已经转移到商业版本里。开源仓库仍然存在但更多只是作为“免费版本”保留下来。它依旧会发布新版本但大多数只是版本号的更新以及进行一些与付费产品无关的改动。于是人们当初采用的那个“开源项目”实际上已经慢慢变成了另一个规模更小、能力更弱的东西。只是它从来没有改过名字。推荐阅读苏姿丰谈AMD扎根中国30年、对话李开复AI转型只能由CEO亲自挂帅别只听CIO的三周、1.81倍、百亿中国AI的压制性时刻Google搜索迎25年来最大改版Gemini Omni和3.5 Flash两大模型重磅发布免费领取 100 小时 AI 算力CSDN 读者福利加入 AI 开发者计划获取✅ AI 算力资源✅ 官方技术社群✅ Workshop 与 AI Academy✅ 开发者专属福利立即扫码前 50 名额外领取「瑞幸咖啡」咖啡领取地址https://s.csdn.cn/4nPsOp