我作為自籌創業者的第七年
七年前,我辭去了在 Google 擔任開發者的工作,創立了自己的自籌軟體公司。每年,我都會發文更新近況,分享進展以及作為獨立創業者的生活樣貌。
我賣掉了公司
過去一年對我職涯最重要的發展,就是賣掉了我在 2020 年創立的公司TinyPilot。
我和太太想要共組家庭,而我認為自己無法同時勝任一家七人公司的唯一管理者,又成為新生兒的好父親。我找到了一位對公司願景與我一致的買家,並在 2024 年 4 月完成了交易。

我賣掉 TinyPilot 以便成家
我已經撰文並在 Podcast 上分享了關於這次出售以及學到的經驗,但簡而言之,我很感激一切都有好的結果。
我成為了新手父親
八月,我和太太迎來了我們的第一個孩子,是個兒子。
寶寶出生後不久,其中一位護理師幫我們三人拍了一張很美的合照,我放在下方。為了保護兒子的隱私,我用手工微調的快速傅立葉轉換處理了這張照片,以移除生物特徵細節:

我、太太與新生兒子的合照,經隱私保護濾鏡後製處理
我很感謝身為獨立創業者所擁有的彈性,以及出售 TinyPilot 的時機點,因為過去五個月是我人生中最快樂的時光。
我投入了教育產品
我在四月賣掉了 TinyPilot,但留到五月中旬協助新東家完成交接。
兒子預產期在八月,我知道他出生後會休一段時間。這讓我在那之前還有三個月可以開展新計畫,但這個計畫必須是那種可以暫擱幾個月、等我適應有孩子後的生活再繼續的類型。
我決定那三個月最適合的產品是可下載的課程或書籍。教育產品很容易暫停,即便已有付費用戶,也不需要維持伺服器運作或回覆客服問題。
我唯一製作教育產品的經驗是在 2021 年。我錄製了一門關於面向技術族群的部落格寫作的影片課程。它在第一年賺了 7,600 美元,之後又賺了 2,200 美元。以課程創作者的標準來看不算爆款,但我只花了約 100 小時製作,而且我對內容感到自豪。這是我成為獨立創業者以來投資報酬率最高的專案。

我 2021 年關於面向技術族群的部落格寫作的課程在四年間總共賺了 1 萬美元。
夏天時,我重新整理了 2021 年部落格課程的教材。我先以每週線上視訊直播的方式,教一小群學生。我的計畫是根據學生的回饋持續優化課程,然後錄製最終可下載的版本來販售。
直播課程進行得還算順利,但學生的回饋是希望多學寫作技巧、少學如何吸引讀者。我原本仍想完成課程,但兒子提早了幾週出生,所以我始終沒能完成錄製。
兒子出生後,在家錄影變得更困難,所以我改為撰寫一本關於開發者高效寫作技巧的書。我以逐章發布的方式推出,並根據讀者回饋不斷迭代內容。
我還有一堆已部分錄製的部落格課程影片,不知該如何處理,所以在此分享其中一支,講的是如果知名的自籌創業作家Patrick McKenzie(派崔克·麥肯錫)向你發起部落格對決,為什麼你應該答應:
我學了很酷的技術
經營 TinyPilot 期間,我沒有時間做技術工作,這讓人有點沮喪,因為我熱愛寫程式。
我一直熱愛寫程式,但在過去一年中,我從未覺得它如此令人興奮。那些免費提供的優秀開源軟體讓我讚嘆不已。
Nix
過去一年對我工作影響最大的技術是Nix 與 NixOS。
Nix 是一個像apt-get或yum的套件管理器,同時也是一個像 CMake 或 Bazel 的建置工具。透過整合這兩種功能,Nix 讓你能輕鬆管理軟體專案的相依套件,並將其打包發布。
我一點一滴地導入 Nix,但因為太喜歡它,現在每個程式專案都使用 Nix,所有的電腦也都運行 NixOS。
- 適合誰嘗試?
- 欣賞像 Docker、Ansible 和 Terraform 這類基礎架構即程式碼工具的開發者。
- 我的推薦理由是?
- 在軟體專案中,Nix 讓你能在原始碼中定義所有相依套件,任何人都能用一行指令複製你的環境。
- NixOS 是圍繞 Nix 概念設計的 Linux 發行版,讓你能用純文字檔定義整台電腦的設定,輕鬆從零重建系統或回滾到先前的設定。
- Nix 具備 Docker 的許多優點,但 Nix 套件的組合性比 Docker 映像更好。
- 缺點是什麼?
- Nix 學習曲線陡峭,我還沒找到適合開發者的優質入門指南,最接近的是NixOS in Production(《正式環境中的 NixOS》),但它是針對 DevOps 工程師寫的。
- 圍繞名為「flakes」的功能存在分歧,如果你使用 flakes,就很難理解沒使用它的教學與文件,反之亦然。
- Nix 社群因領導不善而處於不健康的狀態。
- 在持續整合(CI)中,Nix 對於小型任務的擴展性不佳,除非改用專為 Nix 設計的 CI 廠商,否則我找不到任何能在 55 秒內跑完依賴 Nix 的 CI 任務的方法(相關討論)。
- 有什麼好的探索方式?
- 小步嘗試 Nix,即使只學會其中一小部分功能,也能獲得巨大的價值。
- 使用Determinate Systems 提供的安裝程式安裝 Nix,並試著用
nix shell執行程式(例如nix shell -p cowsay然後執行cowsay howdy, human)。搜尋套件庫,看看有哪些套件能用一行指令安裝。 - 如果你喜歡臨時 shell,可以為其中一個專案建立開發環境 shell,這樣就能用單一檔案管理所有相依套件與開發工具。
htmx
朋友們幾年來一直在稱讚htmx,但這個概念始終沒有讓我開竅。
「你可以讓 HTML 的<button>元素發送 POST 請求?那又怎樣?」
然後,在一次長途飛行中,我讀了關於 htmx 理念的免費電子書Hypermedia Systems(《超媒體系統》)。這本書讓我意識到,htmx 的價值不在於讓<button>能發送 POST 請求,而是在於為 HTML 帶來簡單的互動性,同時不必讓開發者負擔客製化的 JavaScript 或深層的抽象層。
我一直知道網頁開發涉及大量繁瑣的 JavaScript,但我早已將其視為常態。HTML 和 CSS 負責呈現,JavaScript 負責互動,兩者之間必定需要膠水程式碼,而膠水程式碼本來就很枯燥。
htmx 的主張是,你可以透過將更多互動性帶到網頁應用程式的 HTML/CSS 部分,來消除膠水程式碼和樣板 JavaScript。而且你不需要引入像 npm、Webpack 和龐大前端框架那樣的複雜性與相依套件就能做到。
- 適合誰嘗試?
- 偏好原生 JavaScript 或 jQuery 而非 React 和 Vue 等重量級框架的開發者。
- 我的推薦理由是?
- htmx 會讓你意識到自己一生中寫了多少不必要的 JavaScript。
- htmx 是一個函式庫而非框架,因此採用 htmx 不像 React 或 Vue 那樣非全有即全無,你可以在網頁應用程式的單一表單上試用 htmx,看看是否喜歡。
- 沒有建置步驟,所以你不需要透過 Webpack / Node.js 來產生純文字的 HTML、CSS 和 JavaScript,你寫的程式碼就是在瀏覽器中執行的程式碼。
- 缺點是什麼?
- 我發現要轉換為 htmx 的網頁應用程式寫法很有挑戰性,但通常會產生更簡潔的程式碼。
- 我覺得 htmx 的錯誤處理不太順手,不過我有一個還不錯的解法。
- htmx 會弱化內容安全政策(Content Security Policy,CSP)。
- 有什麼好的探索方式?
- 閱讀我更詳細的 htmx 推薦。
- 閱讀我將 ScreenJournal 移植到 htmx 的經驗。
- 閱讀《超媒體系統》的前幾章(免費線上閱讀),看看是否引起你的共鳴。
- 在你的網頁應用程式中,挑一個表單試試 htmx。
Zig
Zig 的理念是,仍有許多程式需要用像 C 這樣的低階語言撰寫,但我們若繼續用 50 年前的程式語言來寫,只會讓自己更辛苦。
Zig 提供了與 C 相同的能力與效能,但利用了 C 語言誕生時尚未出現的硬體與編譯器進展。
我立刻就愛上了 Zig 的理念,但一直找不到適合的專案來使用它。我已經 15 年沒有在個人專案中使用 C 或 C++,我通常做的是小型的網頁應用程式,而 Zig 並不是這類專案的最佳工具。
我仍覺得 Zig 非常有趣。如果我帶著一台筆電但沒有網路,在荒島上受困一年,我夢想中的活動就是把童年電腦遊戲之一的開源重製版(例如Age of Empires II、Command and Conquer)從粗糙的 C++ 程式碼移植成優雅的 Zig。
- 適合誰嘗試?
- 對這些語言的現代重新詮釋感到好奇的 C/C++ 程式設計師。
- 我的推薦理由是?
- Zig 是我久違感到最有趣的程式語言,而我本來就覺得寫程式很有趣。用極低抽象層級寫程式有種額外的樂趣,能完全掌控應用程式對一塊記憶體的存取次數,讓人感到暢快。
- Zig 針對明確的控制流程與記憶體配置進行優化,因此我覺得 Zig 程式碼很容易理解。
- Zig 社群友善且正向,每當我提問,都能得到耐心且有幫助的回答。當我分享Zig 教學時,社群也熱情地歡迎。
- 缺點是什麼?
- 有什麼好的探索方式?
- 挑一個你平常會用 C 或 C++ 寫的簡單程式,改用 Zig 來寫。
- 試試Ziglings,這是學習 Zig 的入門練習。
- Ziglings 練習依賴 Zig 編譯器的預發布版本,如果你有 Nix,取得最新預發布 Zig 編譯器最簡單的方法是執行:
nix shell 'github:mitchellh/zig-overlay#master'
- Ziglings 練習依賴 Zig 編譯器的預發布版本,如果你有 Nix,取得最新預發布 Zig 編譯器最簡單的方法是執行:
透過 Nix 進行 Fuzz testing(模糊測試)
你可能以為我已經講完 Nix 了,才沒有呢!
我一直很好奇想嘗試 fuzz testing 來尋找安全漏洞,因為自我十年前在 VLC 中發現嚴重漏洞後,就沒再使用過模糊測試工具。
我很喜歡Antonio Morales(安東尼奧·莫拉雷斯)2021 年的 fuzz testing 教學,但所有練習在建置可運作的模糊測試環境時,都涉及枯燥的瑣碎工作。
我嘗試了用 Nix 實作模糊測試工作流程,結果好得多。我希望有時間用 Nix 製作更多模糊測試教學,因為我覺得大家都低估了 Nix 作為模糊測試工具的價值。
- 適合誰嘗試?
- 任何從事 fuzz testing 的人,特別是針對 C/C++ 程式碼的人。
- 我的推薦理由是?
- Nix 讓模糊測試工作流程可重現。
- 一旦你在 Nix 下讓模糊測試器跑起來,任何人只要輸入
nix run就能執行你的模糊測試設定,他們不需要費心處理相依套件,因為 Nix 會自動重現你使用的完整環境。
- 一旦你在 Nix 下讓模糊測試器跑起來,任何人只要輸入
- Nix 簡化了相依套件的安裝。
- Nix 擁有所有套件管理器中最大的套件庫之一,如果你的模糊測試目標有相依套件,它們很可能已在 Nix 套件庫中,因此你不必為每個相依套件找出特殊的建置流程。
- Nix 簡化了自訂修補程式。
- 如果需要套用自訂修補程式來對目標進行模糊測試,Nix 讓你能輕鬆套用,並將修補檔與模糊測試工作流程的其他部分放在同一個原始碼樹中。
- Nix 會快取建置結果。
- 如果你嘗試不同的編譯選項,不必每次都從頭編譯,Nix 會記住你是否曾用相同選項編譯過,並重複使用該建置結果,你永遠不需要手動執行
make clean或刪除二進位檔。
- 如果你嘗試不同的編譯選項,不必每次都從頭編譯,Nix 會記住你是否曾用相同選項編譯過,並重複使用該建置結果,你永遠不需要手動執行
- Nix 讓模糊測試工作流程可重現。
- 缺點是什麼?
- 你必須弄清楚如何透過 Nix 這個額外的抽象層來建置你要測試的程式碼。
- Nix 會施展魔法來幫你建置基於 CMake 的專案,但 Nix 的建置選項都是隱含的,這讓它的行為難以理解。
- 我在讓 Nix 產生除錯符號時遇到了困難,到現在還不確定自己做錯了什麼。
- 有什麼好的探索方式?
- 試試我的新手友善教學,了解我如何使用 Nix 和 honggfuzz 為開源 PDF 閱讀器建立模糊測試工作流程。
整體來說,這一年過得如何?
每年,我都會問自己是否仍然享受作為獨立創業者的生活。
過去幾年,我很難回答這個問題。經營 TinyPilot 時,我為公司感到驕傲,也很喜歡與 TinyPilot 團隊共事,但我覺得硬體公司的步調與複雜度對我而言太過沉重。
今年,我重新享受起獨立創業者的身分。我喜愛能花這麼多時間與太太和兒子相處的自由,也很感激重返工作的時機完全由我決定,我能完全掌控如何以及何時將工作融入有孩子後的生活。
出售 TinyPilot 的過程充滿壓力且不愉快,但回首時,我記得的是與太太和朋友們在麻州西部的即興甜點之旅中慶祝的時光。
五月時,一位 Google 的招募人員免面試就邀我回鍋原職,但我一點也不心動。
我依然享受獨立創業者的生活,也希望能盡可能長久地持續下去。
學到的教訓
不工作也沒關係
兒子出生前,我一直在掙扎要休多久。顯然,休一個月沒問題,但如果一個月可以,為什麼不兩個月?為什麼不四個月?為什麼不一年?
兒子出生後的幾個月,我突然沒有了空閒時間。我開始苦惱一個更可怕的問題:如果有了孩子之後,即便我想回去工作也回不去怎麼辦?如果我再也無法擁有足夠不被打斷的時間來寫作和寫程式怎麼辦?
我深吸一口氣,意識到我之所以「沒有空閒時間」,是因為每週有好幾天,我會和太太、兒子一起在市區長時間散步、享受戶外早午餐,或是招待從外地來探望寶寶的訪客。我必須提醒自己,這些都是好事,是我喜歡做的事,而且如果我決定恢復工作,我仍然掌控著自己的時間。
最終,我重返工作是自然而然發生的,並未與家庭時間產生衝突。我和太太找到了適合我們的育兒平衡,並隨著兒子長大、其他家人也加入協助育兒,我們持續進行調整。
只有當別人實際使用文件時,流程才算真正被記錄下來
在出售 TinyPilot 前的幾個月,我專注於盡可能將工作委派給團隊其他成員。我不希望新東家接手後,覺得有某些關鍵任務無法完成,只因為只有我知道怎麼做。
我以為委派會很輕鬆,因為我們對每件事都有操作手冊,甚至包括我自己負責的工作。當我開始把任務交給隊友時,才意識到許多我負責的「已記錄」流程其實都只存在於我的腦中。像「撰寫發布公告」或「更新公開的變更日誌」這樣的步驟,遠比簡短的描述來得複雜。
現在我認為,只有當隊友能僅靠文件就完成流程時,這個流程才算真正被記錄下來。
賣給現金買家能大幅降低風險與文書作業
出售 TinyPilot 最大的教訓之一,就是成交時間的長短會帶來多大的差異。我沒意識到交易每拖一個月,賣方就要承擔多少額外的風險與文書作業。

買方的資金來源對成交時間有重大影響。如果買方跟銀行借款,銀行就會成為交易中的關鍵決策者。銀行動作緩慢、要求大量文書,而且很難協商,因為他們不在乎交易是否破局。
如果我再賣另一家公司,我會提供誘因來吸引手上有現金的買家。
回顧去年目標的達成度
去年,我設定了三個高層次目標希望在這一年達成,以下是達成狀況:
每週用 20 小時管理 TinyPilot
- 結果:每週管理時間降至 20 小時
- 評分:A
我在四月賣掉了公司,所以這一年只有很短的時間在管理 TinyPilot,但我終於達成了每週只用 20 小時管理的目標,這是我過去三年重複設定的目標。
最終能實現的原因是我別無選擇,盡職調查與管理公司出售事宜本身就佔用了每週 15 到 20 小時,所以我根本沒有多餘的時間去做以前做的事。幸好,團隊挺身而出,接手了我先前沒想到要委派的工作。
出版一門課程或一本書
- 結果:開了直播課程,但未出版課程或書籍
- 評分:C
如果跳過直播版本,我很可能已經發布了課程,但我仍很高興做了試教,因為它讓我獲得了關於課程重點的寶貴回饋。
每週寫程式十個工作小時
- 結果:每週寫程式 10 到 20 小時
- 評分:A
我現在更頻繁地寫程式,而且樂在其中。
明年的目標
獲利 5 萬美元
在所有產品中,我希望獲利 5 萬美元。不必是經常性收入,一次性銷售也算,但我想找到一種方式,透過銷售自己的產品至少賺進 5 萬美元。
出版一門課程或一本書
我自 2021 年起每年都設定出版一本書的目標,從未達成,但今年感覺就是時候了。
學習一個新的程式語言
每當我學習一個新的程式語言,都能獲得可應用於整體程式設計的洞見。
隨機一篇部落格