Launching a Side Project Backed by Github Sponsors

Matthias Endler

發表一個由 Github Sponsors 資助的副專案

昨天我們推出了 analysis-tools.dev,老實說,我完全低估了大家的迴響。

這是一個用來比較靜態程式碼分析工具的副專案。靜態分析能在不執行程式碼的情況下,透過偵測原始碼中的錯誤來提升程式碼品質。

這個專案最棒的地方在於它是完全開源的。我們想打造一個不依賴廣告或追蹤使用者的產品。相反地,我們只在 Github 上尋求贊助——就這樣而已。我們在過程中學到很多,如果你也想這麼做,請繼續看下去!

首先,來看看一些數據

大家都喜歡商業數據。以下是我們的數據:

  • 這個專案最初是 Github 上的一個 awesome list,始於2015 年 12 月
  • 目前我們收錄了 470 個靜態分析工具。
  • 流量持續成長。目前累計 7.5k 顆星、超過 190 位貢獻者。
  • 每週 500 至 1000 位不重複訪客。
  • 我好幾年前就想做一個網站了,但直到 2020 年 5 月,同事 Jakub(雅庫布) 加入,才終於讓它成真。
Github 星標數隨時間的變化。這張圖大喊著商機。
Github 星標數隨時間的變化。這張圖大喊著商機。
來源:star-history.t9t.io

「為什麼花了五年才做一個網站!?」,我聽到你在問。因為我以為這個點子太過顯而易見,肯定早就有人試過而且失敗了。

我一直拖延,即使沒有人來填補這個利基市場。
我一直拖延,即使這五年來我持續更新這份清單,只是為了了解市面上有哪些工具。
你懂我的意思了:別把事情拖太久。當一個點子聽起來很顯而易見,很可能就是因為它真的很顯而易見。

營收模式

我們花了一段時間才想清楚要如何讓這個專案在財務上得以維持。我們很清楚自己不想要什麼:一個靠 AdWords 撐起來的 SEO 內容農場。我們也不想把使用者資料賣給追蹤程式。

我們對 Github 上的貢獻者有責任,要讓所有資料對每個人都免費開放。那我們還能如何圍繞它打造服務呢?一開始,我們考慮自行吸收基礎設施成本,但那樣我們就沒有誘因去維護網站或新增功能了。

Github Sponsors 在當時還相當新。然而,一旦我們意識到這是一個選項,事情就豁然開朗了:不怕與競爭對手比較的公司,會有誘因去支持一個能促進這種比較的開放平台。此外,我們可以避免偏見,打造一個讓比較更客觀、更容易取得的產品。

贊助或許能成為對抗空洞成長的解藥,讓我們得以打造一個精實、永續的副業。我們並不期待 analysis-tools.dev 有朝一日會變成一份正職工作。這個市場或許太小了——但這樣也很好。

技術

有了營收模式後,我們就能專注在技術上了。我們兩個都是工程師,這有助於快速迭代。

一開始,我想用 Yew 來做個華麗的東西。它是一個 Rust/Webassembly 框架,而且小弟就喜歡 Rust/Webassembly……

我很高興雅庫布建議了別的方案:Gatsby。現在,老實跟你說:我對 Gatsby 一點都不在乎。我就是這樣跟雅庫布說的:「我對 Gatsby 一點都不在乎。」但重點就在這裡:對某個東西沒有情感上的執著,反而讓我們能專注在工作本身,而不是工具上。這樣我們反而能完成更多事!

從那之後,事情就大致順利了:我們用了一個 starter template,雅庫布向我展示了 GraphQL 整合是如何運作的,而且我們甚至還用到了一些 Rust!這個網站以edge worker 的形式運行在 Cloudflare 上,而且是用 Rust 打造的。(對,我有點作弊了。)

數到三,MVP 誕生!

尋找贊助者

所以我們有了原型,但目前還沒有任何贊助者。接下來開始的(而且到現在仍是)目前為止最困難的部分:說服人們支持我們。

我們很聰明地沒有寄送陌生開發信,因為大多數公司根本不會理會。相反地,我們轉向自己的人脈,並意識到過去曾有開發者主動聯繫我們,希望將他們公司的專案加入 Github 上那份舊的靜態分析清單中。

這些就是我們最先聯繫的對象。我們盡量讓訊息保持簡短且具個人化。

最有效的方式是一封中等長度、帶有背景脈絡的電子郵件,並提醒對方他們曾經為這個專案做出貢獻。我們在信中附上了贊助頁面的連結。

企業想要可靠的合作夥伴和合理的價值主張,因此先決條件是贊助頁面必須經過一絲不苟的打磨。

我們的 Github Sponsors 頁面
我們的 Github Sponsors 頁面

就像 Star Wars Episode IX(《STAR WARS:天行者的崛起》)一樣,我們得到的評價好壞參半:很多人從未回覆,其他人則把訊息轉給主管,然後主管也從未回覆,還有一些人則是對贊助開源專案根本沒興趣。這都無可厚非:大家都很忙,而 sponsorware 還是一個相當新的概念。

小小抱怨一下:我認為科技公司從開源獲得了這麼多價值,給予的贊助卻遠遠不夠。如果當初創立公司時沒有像 Linux 這樣的免費作業系統,或像 Nginx、Apache 這樣的網頁伺服器,你的公司還會存在嗎?

然而,有一種少見的回覆者,他們表達了興趣,但需要一些指引。對許多人來說,這是他們第一次透過 Github Sponsors / OpenCollective 贊助任何開發者。

幸好我們使用 OpenCollective 作為我們的 fiscal host(財務託管單位),它負責處理開立發票和捐款轉帳。他們的文件在我們剛起步時幫了大忙。

尋找贊助者的任務永遠不會結束,但聽到 DeepCode——一家提供 AI 驅動語意分析服務的公司——願意給我們一個機會時,還是讓人非常安心。

多虧了他們,我們才能讓產品跨過終點線。因為有他們,我們才能讓網站對所有人保持免費。這也意味著網站不會有廣告和追蹤程式。

反過來,DeepCode 也能接觸到許多重視程式碼品質的優秀開發者,而這些開發者可能會成為他們的忠實客戶。同時,他們也能被認可為一家對開源友善的科技公司,而這在你試圖銷售開發者工具時,比以往任何時候都更加重要。雙贏!

行銷

雅庫布和我以前都創過業,但這是我們第一次真正打造一個開放的產品。

第一階段:及早發布 🚀

我們決定採取軟性上線:盡早部署網站,讓爬蟲來索引。由於頁面是靜態產生且遵循了一些基本的 SEO 準則,確實有助於我們隨時間提升搜尋引擎排名。

第二階段:向目標族群徵求回饋 💬

在獲得一些自然流量和最初的投票後,我們聯繫了開發者朋友來測試頁面,並為他們熟悉喜愛的工具投票。這算是早期的驗證,我們也得到了一些誠實的回饋,幫助我們抓出了最明顯的缺陷。

第三階段:準備發布文章 📝

我們寫了一篇部落格文章,雖然有點標題黨,但確實達到了目的:Static Analysis is Broken — Let’s Fix It! 它大致捕捉了我們對這個領域的挫折感,以及為什麼打造一個開放平台很重要。我們本可以在解釋不同分析工具之間的技術差異上做得更好,但那就留待下次再說吧。

第四階段:在社群媒體上發布 🔥

在正式發布前不久,我們注意到搜尋功能壞了(當然)。原來,我們比預期中更快地用完了 Algolia 的免費額度。😅 沒什麼大不了的:跟 Algolia 客服快速聯繫後,他們就把我們轉到了開源方案(我們原本不知道有這個方案)。我們又回到正軌了!

題外話:Algolia 的客戶支援是一流的。回應迅速、懂技術又樂於助人。使用 Algolia 結果證明非常適合我們的產品。回應時間始終保持在幾毫秒內,而且與 Gatsby 的整合既快速又簡單。

那則推文帶來了不少關注:63 次轉推、86 個讚,而且還在持續增加
那則推文帶來了不少關注:63 次轉推、86 個讚,而且還在持續增加

顯然,大家都知道我們是在尋求支持,但我們對每一個按讚和轉推的人都心存感激。在這種情況下,擁有一個志同道合的人脈網絡確實能幫上大忙。

一旦我們確定網站不是完全壞掉後,就著手在 Lobste.rs(2 個倒讚)、/r/SideProject(3 個讚)和 Hacker News(173 個讚、57 則留言)上發布。社群媒體有點難以預測。雖然如此,針對每個社群量身打造訊息並保持謙遜,還是會有所幫助。

所有這些行銷努力帶來的回應是瘋狂的

發布當日的流量
發布當日的流量

或許毫不意外,Cloudflare 的 edge workers 連眉頭都沒皺一下。

在 Cloudflare 上的 Edge Worker CPU 時間
在 Cloudflare 上的 Edge Worker CPU 時間

我的老闆 Xoan Vilas(索安・維拉斯) 甚至還做了一個快速的效能分析,而且他也認可了。(謝謝老闆!)

大家互相擊掌!

接下來呢?

當然,我們會加入新功能;當然,我們對未來還有更多計畫,諸如此類。但與其說這些,不如來回顧一下這個里程碑:一個沒有廣告或追蹤程式、僅靠贊助者支撐的健康小事業。🎉

最後,我希望你好好審視自己,找出屬於你自己的小產品來投入。它很可能就在你眼前,就像我一樣,你已經拖延太久了。好吧,別再拖了!下一個成功故事就是你的。所以走出去動手打造吧。

喔對了!……在你離開之前,能不能幫忙看一下 analysis-tools.dev,並為你喜歡的幾個工具大力按下讚賞按鈕?嘿,如果你今天特別慷慨(或者你有一個關心開源的超棒雇主),何不看看我們的贊助頁面呢?

雅庫布和我在奧地利維也納。我其實沒有那麼矮。
雅庫布和我在奧地利維也納。我其實沒有那麼矮。

原文由 Matthias Endler 發布

本文章由 muse-spark-1.2-contributor 進行翻譯