流行的开源软件在让不少公司节省大量资源、成本的同时,也让他们赚得盆满钵满。然而,深挖其背后,辛苦开发的个人开源开发者却得不到任何回报,最终因自己的贡献而陷入沉思、反抗的也不在少数。
三年前,Curl 创始人兼首席开发者 Daniel Stenberg 就曾在自己博客发出怒吼,剑指苹果公司称:“作为经营一家价值数万亿美元的公司,苹果将各种开源组件捆绑到自己的产品中,每年赚取数十亿美元的利润。当这家公司用户在使用他们产品出现问题寻求帮助的时候,苹果却将问题推给开源项目。而且苹果并未给这个项目赞助过一分钱,为什么我要成为你产品的免费客服。”
自此之后,陆续也有不少开源项目作者加入“暴力拒绝白嫖”的队伍,开源库「faker.js」和「colors.js」库作者 Marak Squires 直接选择删库而导致数千个应用程序无限输出乱码便是一个典型的案例。
与 Daniel Stenberg、Marak Squires 等开源作者所面临的“困境”颇有相似的还有 Node.js 电子邮件发送库 Nodemailer 的作者 Andris Reinman,只不过有所不同的是,他开启了“自救”模式,将开源项目变成了一项业务。
经过了时间的积累,Andris Reinman 的这一项目现在 MRR(月经常性收入)达到了 6100 欧元(约 4.7 万元),而且还在稳步增长。
接下来,我们将通过他的自述,了解其开源心路演变历程与做法。
“15 年前的我,希望通过开源让更多的人受益”
大约 15 年前,当我开始编写和发布开源软件时,我充满了激情。
那时的我,只使用 MIT 或 BSD 这样相对宽松的软件许可,因为我关心的只是我的开源软件能够带来多大的影响力。倘若使用附带条件的版权许可似乎会阻碍这种影响力的发展。
那时的我,也认为让另一家 A 类公司使用我的开源库(如 Nodemailer,从 Node.js 发送电子邮件组件,https://github.com/nodemailer/nodemailer/)是一种荣誉。甚至,当一家大型交易电子邮件服务公司的创始人给我发来一封关于 Nodemailer 的邮件并表示愿意捐款支持我的开源工作时,我给拒绝了。
那时的我,只是单纯地不想让自己看起来受到其中一家主要提供商的影响,因为这会对其他使用者造成不公平。
现在事后看来,我真是个傻瓜。
一切状态就这样持续了几年,直到某一天,当一家使用 Nodemailer 的初创公司以 5 亿美元的价格被收购时,我的想法发生了翻天覆地的变化。
由于我当时的经济状况并不好,当看到这个消息后,我开始思考——我从中得到了什么?发送电子邮件通知是这家初创公司提供服务的重要组成部分,他们每天可能要使用 Nodemailer 发送数百万封电子邮件通知。至少,我提供了一个免费、可靠的邮件发送库,为他们节省了大量的开发时间。
后来,我在自己的邮箱中搜索了与该公司相关的邮件,却发现只有一封关于他们对一个功能投诉的邮件。
没有拉取请求(PR),没有捐赠,什么都没有。
我也无处投诉,因为我在知情的情况下将自己的软件提供给全世界使用,却没有要求任何补偿。
我空空如也的钱包对于这样事态的发展很不满意。
惊醒与改变
因此,当我开始开发电子邮件客户端 EmailEngine 这款软件时,我尽可能地低调,并掩饰自己。
EmailEngine 是一个自助托管的电子邮件自动化平台,可通过用户友好的 HTTP REST API 轻松访问电子邮件账户,用来接收和发送电子邮件。该平台会主动监控这些账户,并在有任何更新时发送 webhook 通知。
我在 LGPL 许可下发布了软件。我还设置了一个自动的 CLA(Contributor License Agreement,贡献者许可协议,简单来说就是项目接收贡献者提交的 Pull Request 之前,需要贡献者签署的一份协议,协议只需签署一次,对该贡献者的所有提交都生效)流程,这样任何人在没有签署 CLA 的情况下,都无法合并他们的 PR。
很多人都讨厌 CLA,有几个人先打开了 PR(pull request),但一旦意识到有 CLA 的要求,就关闭了 PR。
老实说,我并不在意。因为 Nodemailer 98.1% 的代码都是我自己写的,只有 1.9% 来自其他贡献者,所以无法合并 PR 并不是什么大问题。至于 EmailEngine,在开源一年半之后,同样的数字是 99.8% 对 0.2%。
我使用 CLA Assistant(https://cla-assistant.io/?ref=docs.emailengine.app)管理项目中的 CLA
显然,我想从我的新项目中赚点钱,我的商业计划很简单。
我将该项目(当时名为 IMAP API)作为 LGPL 许可的应用程序发布。我还提供了一个 MIT 版本,但要获得该版本,你必须订阅。订阅费为每年 250 欧元(约 1949 元)。
我的假设是,软件的主要目标客户——公司并不喜欢版权许可,一旦他们看到应用程序的实用性,就会转用许可协议。
事实证明,我的商业计划太疯狂了。最终我只获得了几个付费用户,而且在我看来,这些人根本没有使用 IMAP API。他们只是想支持一下我的工作,对我的努力做了认可。
事实证明,小公司根本不在乎许可证,大公司也不使用它。
经过一年半的时间和 750 欧元的总收入后,我决定放弃——不再提供免费的东西了。
我重新设计了应用程序的用户界面,使它们看起来更专业,并实施了许可证密钥系统。
从那时起,如果你想使用 EmailEngine(IMAP API 的新名称),你需要一个许可证密钥,只有付费用户才能使用。
我还将许可证从 LGPL 更改为商业许可证。源代码仍在 GitHub(https://github.com/postalsys/emailengine)上公开发布。
根据定义,它不再是开源的,而是源代码可用的。之所以能做出这样的许可变更,是因为从一开始就要求外部提交者签署 CLA。
我仍在发布 MIT 许可的项目,但仅限于小型工具,而非大型项目。这些工具的目标是促进我的主要工作。例如,我从 EmailEngine 中提取了 IMAP 客户端函数,并在 MIT 许可下将其作为 Node.js 的通用 IMAP 客户端库发布。这个模块(ImapFlow)的采用率越来越高,因为它远远优于任何已有的替代方案。文档页面每月为 EmailEngine 的主页带来约 100 名访问者,虽然数量不多,但这是免费流量,而且有时这些访问者会进行转换,从而使我们的努力卓有成效。
起初,这款软件甚至没有试用选项。如果你在程序启动 15 分钟后没有提供有效的许可证密钥,程序就会停止工作。
我保持价格不变,每年 250 欧元,在第一个月,我卖出了价值 1750 欧元的订阅。这相当于我前一年半收入的两倍,也决定了这个项目的命运。
我再也没有回头路了。
接下来,我开始提高定价:250 欧元变成 495 欧元,然后是 695 欧元和 795 欧元,最后是 895 欧元。令我惊讶的是,客户数量并没有因此减少。
我想,任何低于 1000 欧元的价格对于企业来说都是小数目,因此这些价格上涨所改变的唯一事情就是提高了收入。
目前,EmailEngine 的 MRR 为 6100 欧元(约 4.7 万元),而且还在稳步增长,在我居住的爱沙尼亚,这让我可以支付自己一份体面的薪水,从而可以全职从事我的项目。
我唯一的遗憾是没有更早地开始销售我的软件,而只是发布了免费的开源软件。
是的,我在 GitHub 上有一些赞助商,但数额一直不大,每月从 50 美元到 750 美元不等,这取决于我碰巧遇到多少赞助商。向企业客户销售肯定比依靠随机人群的善意更可靠、更可预测。
开源开发者的现状
Andris Reinman 的经历也引发了不少开源开发者的共鸣,甚至登上了 HN 的热榜:
网友 ergonaught 表示:
当看到“无论如何,几年后,当一家使用 Nodemailer 的初创公司以 5 亿美元的价格被收购时,情况发生了变化。当时我的经济状况并不好,看到这个消息后,我开始思考--我从中得到了什么?”时,这就是大多数类似 BSL(商业源码许可证)诞生的根源。
你创建了一个开源项目或产品,而那些每季度收入数十亿美元的公司却把他们的核心业务建立在你的软件上,与此同时,他们不会为你的持续生存(更不用说实际的成功)做出任何贡献,哪怕是对他们来说微不足道的贡献。现在再加上云计算提供商,情况就更糟糕了。
也有用户 ThePhysicist 评价道:
他做得好!这也是我使用开源软件的经验,如果某样东西是免费的,公司几乎永远不会为它付费,即使他们从中获得了大量价值。另一方面,如果只是少量的费用,例如每年 1,000 美元,大多数公司都会让开发人员购买,而不需要太多的手续。如果进入企业销售领域,情况就会变得复杂,销售周期也会更长。对于不需要超大规模的个人创始人来说,这种定价方案似乎再合适不过了。
不过对于 Andris Reinman 选择将开源许可变为商业许可的这种做法,也有网友认为并不可取:
「我对商业软件没有意见,对开源软件也没有意见,但我对开发者将自己的代码作为开源软件发布,在敲响开源号角的同时建立社区,然后在他们认为自己已经拥有了足够多的受众,可以从中牟利时,又将软件推向商业化的做法有意见。
我想说的是,如果你最终想在你的项目上赚钱,至少在一开始就直言不讳,这样你的用户在决定是否将其纳入他们的堆栈时就能做出明智的决定。」
基于此,你怎么看?
来源:
https://news.ycombinator.com/item?id=39522348
https://docs.emailengine.app/how-i-turned-my-open-source-project-into/