實戰案例:我的四個產品
本篇是「一個人做產品」系列的第 13 / 18 篇。你可以從系列總覽開始閱讀,也可以直接接著看本文。
紙上談兵結束,四個 Solo Builder 產品的真實拆解
前 12 章,我們走過了從點子驗證到 Micro SaaS 的完整流程。理論講了很多,框架也建了不少。
但你心裡可能有個問題:「這些真的有人照著做過嗎?」
有。就是我自己。
這一章我要完整拆解我邊上班邊做的四個產品。有意思的是,這四個東西刻意選得很不一樣:一個是塞了七千多筆資料的互動地圖網站、一個是裝在你電腦裡的桌面 App、一個是 Chrome 擴充功能、一個是上架 Google Play 的 Android App。四種平台,四套幾乎沒有交集的技術棧。
先講一句醜話講在前面:這四個沒有一個是搖錢樹。 它們都是免費、開源、搔自己癢處的作品。如果你翻到這章是想看「怎麼靠 side project 賺錢」,那部分我在第 2 章的驗證故事談過。這一章談的是另一件事——一個有正職的人,怎麼真的把四種完全不同的東西「做出來、ship 出去」。
每個產品我會告訴你:
- 做了什麼:產品概述與技術棧
- 關鍵決策:那些影響最大的技術選擇,還有為什麼
- AI 怎麼用:具體的場景,以及它到底幫了什麼
- 現況與投入:一個有正職的人實際的節奏
- 踩過的坑:什麼卡住我最久
準備好了嗎?從第一個開始。
產品一:TaxMap-TW — 台灣所得地圖
概述
| 項目 | 內容 |
|---|---|
| 類型 | 互動資料視覺化網站 |
| 技術棧 | Astro 6 + MapLibre GL + PMTiles + TypeScript |
| 狀態 | 上線運行中 |
| 資料規模 | 7,747 個村里 × 12 年(2012–2023) |
| 營收模式 | 無(開源公民專案) |

🔗 前往網站:taxmap.bobochen.dev ↗
我自己都叫它「哪裡最有錢」。起點很單純:我對財政部公布的綜合所得稅資料很好奇,想知道「到底哪個里最有錢」,但官方 CSV 攤開來就是一堆數字,看不出所以然。於是我把 22 縣市、7,747 個村里、跨 12 年的資料塞進一張可以縮放、可以 PK、可以看趨勢的地圖。
一個資料視覺化網站,看起來沒什麼技術含量。但它其實是這四個產品裡「後端工程」最重的一個——難的不是畫面,是把政府的原始資料清成能上地圖的樣子。
關鍵決策:向量磚(PMTiles)而不是自架圖磚伺服器
要在網頁上畫七千多個村里的邊界,傳統做法是架一台圖磚伺服器(GeoServer、tileserver-gl 那類),前端跟它要圖磚。我沒這樣做。
| 考量 | 自架圖磚伺服器 | PMTiles 單一檔案 |
|---|---|---|
| 基礎設施 | 要一台一直開著的機器 | 一個 5.7 MB 檔案丟 CDN |
| 成本 | 伺服器月費 | 靜態託管,幾乎零成本 |
| 維運 | 要顧伺服器健康 | 沒有伺服器可顧 |
| 部署 | 另外一條 pipeline | 跟網站一起 push 就上去了 |
PMTiles 把整個台灣的村里邊界壓成一個 5.7 MB 的檔案,瀏覽器直接讀,MapLibre GL 負責畫。我用 Felt 那套 tippecanoe 把國土測繪中心的 SHP 圖資轉成簡化過的 GeoJSON,再打包成 PMTiles。
對一個人來說,這個決策的重點是「少一台要顧的伺服器」。這條原則跟第 3 章「選生態系不選框架」一脈相承:能不架伺服器就不架,你的維運心力是有限資源。
關鍵決策:把「產出的資料」也 commit 進 git
這個決策比較反直覺。一般人會把資料處理腳本 commit 進去,但把跑出來的結果(七千多個村里的個別 JSON、排名檔、PMTiles)當成「build 產物」丟給 CI 自己跑。
我反過來——跑出來的資料全部 commit 進 git,大約 7,790 個檔案、134 MB。
為什麼?
- 別人(或未來的我)clone 下來就能跑。 不用先裝一堆地理資訊工具、不用等 pipeline 跑完,
clone完直接dev就有東西看。 - CI 變簡單。 CI 只要
typecheck+astro build,對著已經 commit 好的資料建站,不用在 CI 裡重跑整條資料管線。 - 資料的每次變動都留痕跡。 更新一個年度,git diff 就看得出哪些村里的數字動了。透明、可稽核。
代價是 repo 很肥、更新資料時要記得把重新產出的檔案一起 commit。但對這種「資料一年才更新一次」的專案,我覺得這筆交易很划算。
關鍵決策:固定門檻上色,而不是分位數
地圖上色(choropleth)有兩派:一派用分位數(把當年資料切成幾等份上色),一派用固定門檻。我選固定門檻——收入 300、500、800、1300、2000、3500(千元)這幾個硬切點,套 ColorBrewer 的 OrRd 七階配色。
差別在哪?如果用分位數,「同一個里、同樣的收入,在不同年份可能是不同顏色」,因為每年重新切等份。那樣一來,跨年比較就會騙人。固定門檻的意思是:同樣的收入永遠是同樣的顏色,切年份、切指標只是換 MapLibre 的 paint 屬性,不重算級距。比較才公平。
這種細節使用者不會注意到,但它決定了整張地圖「能不能拿來做嚴肅比較」。
AI 怎麼用
老實說,這個產品裡沒有任何 AI 功能。資料是政府公開統計,地理邊界是國土測繪中心的圖資,沒有一個地方需要 LLM。
但 AI 在「把它做出來」這件事上幫了大忙——我不是 GIS 背景,tippecanoe、PMTiles、MapLibre 的 match 表達式這些東西,我一個都不熟。以前碰到不熟的工具鏈,我大概要花一整個週末讀文件、試錯。這次我讓 AI 當我的地理資訊工具鏈教練:解釋每個工具在整條管線的位置、幫我除錯 tippecanoe 的參數、把我不熟的座標系概念講白。
這是一個貫穿這四個產品的主題,我後面會再回來講:AI 對 solo 開發者最大的價值,往往不是變成產品的功能,而是讓你敢碰完全不熟的技術。
現況與投入
站已經上線,主要的工都花在資料管線上。上線之後我幾乎不用動手——一個每月 1 號跑的 GitHub Actions cron 會去財政部探有沒有新年度資料,有的話自動開一個 PR,我 review 完 merge 就更新了。
一個「上線後幾乎自己養自己」的產品,是有正職的人最喜歡的那種。
踩過的坑
- OG 社群圖沒辦法在 CI 裡產。 七千多個村里各要一張分享圖,在 CI runner 上跑 Satori 直接把記憶體撐爆。最後改成本地產好、打包成 GitHub Release,CI 需要時再下載回來。有些東西就是不能硬塞進 CI。
- 26 個村里怎麼都對不起來。 財政部和國土測繪中心兩邊的村里名稱有些罕用字對不上,7,747 個裡有 26 個(0.34%)永遠 join 不乾淨。我沒有假裝它不存在——對不上的就老實顯示「無資料」,並做了一個字尾相似度的 fallback 去救一部分。
- 2023 年是從 PDF 反推的。 財政部那年還沒出 CSV,只有 22 份縣市 PDF。我寫了個 parser 從 PDF 硬抽,先頂著用,等官方 CSV 出來月更 job 會自動蓋掉。
產品二:TypeLate — 語音轉文字桌面 App
概述
| 項目 | 內容 |
|---|---|
| 類型 | 桌面應用程式(macOS / Windows) |
| 技術棧 | Tauri v2 + React 19 + Rust + SQLite |
| 狀態 | 已發佈 v1.6.2 |
| 開發時間 | 2025/3 首發,14 個月 6 個版本 |
| 營收模式 | 無(免費、開源、MIT) |

🔗 前往網站:typelate.bobochen.dev ↗
TypeLate 是這四個產品裡唯一「你要真的裝進電腦」的東西。它解決一個很具體的痛:我討厭打字。按一個熱鍵、開口講話,三秒內螢幕上就出現整理過的文字,游標在哪它就貼在哪,任何 App 都能用。
它不只是「語音轉文字」——市面上那種很多。差別在後面那個「整理過」:Groq 的 Whisper 先把你講的話轉成逐字稿,接著一個 LLM 把贅字、口頭禪、文法順一遍,才貼出來。原始逐字稿跟能直接用的文字,中間差的就是這一步。
關鍵決策:Tauri 而不是 Electron
要做跨平台桌面 App,最主流的選擇是 Electron。我選了 Tauri。
| 考量 | Electron | Tauri v2 |
|---|---|---|
| 安裝檔大小 | 動輒上百 MB | 幾 MB 到十幾 MB |
| 記憶體 | 吃很凶 | 輕很多 |
| 後端語言 | Node.js | Rust |
| 我熟嗎 | JS 我熟 | Rust 完全不熟(但想學) |
前三行是技術理由,第四行才是誠實的理由——我想學 Rust。 一個沒有 KPI、沒有 deadline 的 side project,正好是拿來練不熟技術的最佳場合。這件事跟第 3 章講的「有正職求快時該統一技術棧」剛好相反,而那正是我當初留的那個例外:當學新東西本身就是目的,「不能複用舊知識」就不是缺點,是重點。
關鍵決策:Groq 雲端,而不是本地 Whisper
語音轉文字可以完全跑在本機(下載 Whisper 模型自己跑),也可以打雲端 API。我選了 Groq。
| 考量 | 本地 Whisper 模型 | Groq 雲端 API |
|---|---|---|
| 速度 | 看你電腦,慢機器很痛 | 穩定 3 秒內 |
| 隱私 | 完全不出你的電腦 | 語音送到 Groq |
| 安裝負擔 | 要先下載好幾 GB 模型 | 只要一把 API key |
| 我的取捨 | — | 選速度,但 key 留在使用者本機 |
Groq 號稱是最快的推論引擎,實測確實能壓進三秒,這是本地模型在一般筆電上很難穩定做到的。隱私上我做了個折衷:使用者填自己的 API key,語音是從使用者電腦直接連到 Groq,不經過我的任何伺服器。我不但看不到你的語音,我也沒有伺服器要維護。對一個人的專案來說,「沒有後端要顧」永遠是加分。
關鍵決策:雙視窗架構
TypeLate 有兩個視窗:一個是設定用的主控台,一個是那個懸浮在螢幕上方、透明、永遠置頂的小 HUD(錄音時你看到的那顆)。它們是兩個獨立的 Tauri 視窗,共用同一個 Rust 後端。
為什麼要拆兩個?因為那顆 HUD 必須「主控台關掉了、或在另一個螢幕上,它照樣能被熱鍵叫出來、照樣運作」。前端跟後端之間用 Tauri 的 invoke(前端叫後端)和 emit(後端通知前端)溝通,職責切得很乾淨。
AI 怎麼用
這是四個產品裡 AI 密度最高的一個,而且是雙重的:
AI 是產品本身。 轉錄(Whisper)跟潤稿(LLM)就是核心功能。更進一步,它會看你現在在哪個 App——在寫 email 就用正式一點的語氣、在 Slack 就口語一點、在 VS Code 就技術一點。同一句話,不同情境,出來的整理方式不一樣。
AI 也是我的 Rust 老師。 前面說了,我不寫 Rust。整個 src-tauri 底下的原生層——音訊擷取、全域熱鍵、剪貼簿、多螢幕的 HUD 定位數學——是我一邊描述要什麼、一邊讓 AI 生 Rust、我再讀懂改掉。沒有 AI,我不會有膽用一個我不熟的語言去做一個要處理系統底層的桌面 App。
現況與投入
v1.0.0 在 2025 年 3 月首發,到 v1.6.2(2026 年 5 月)大概 6 個版本、14 個月。我沒有精確計時,但從 git 看得出節奏——就是「每隔一兩個月推一版」那種下班寫的步調。mac(Intel / Apple Silicon)和 Windows 都有簽好的安裝檔,透過 GitHub Releases 發,App 內建自動更新。整套有 127 個單元測試守著。
踩過的坑
- macOS 的輔助使用權限快取,是我第一號客訴。 macOS 會把權限綁在 App 的簽章上,更新版本之後,那個權限看起來還「打勾」,實際上已經失效。使用者得手動把 TypeLate 移除再加回去。這種 OS 層級的坑,你寫再多程式都繞不掉,只能在說明裡一步步教。
- 未簽章的 binary 有信任摩擦。 macOS 第一次打開會擋,要使用者自己去「隱私權與安全性」放行。這一步嚇跑了多少人我不知道,但它確實是免費開源 App 的隱形門檻。
- 關閉時我用了
_exit(0)這種暴力手段。 Tauri 正常的關閉流程會跟背景的事件監聽 deadlock,我只好硬關。代價是「重啟」得自己重新 spawn 一次 binary。不漂亮,但穩。
產品三:Extension Jetpack — Chrome 擴充功能管理器
概述
| 項目 | 內容 |
|---|---|
| 類型 | Chrome 擴充功能(Manifest V3) |
| 技術棧 | Manifest V3 + Fuse.js + SheetJS |
| 狀態 | v1.0.0,準備上架 Chrome Web Store |
| 語系 | 12 種語言 |
| 營收模式 | 無(免費、無追蹤) |

🔗 前往網站:extension-jetpack.bobochen.dev ↗
這個產品的起點也是自己的癢:我裝了太多擴充功能,每次要開關某一個都得點進 chrome://extensions 那個又長又醜的頁面找。Extension Jetpack 就是一個鍵盤優先的啟動器——按 Cmd/Ctrl+J,跳出一個可以搜尋的清單,開關、移除、進設定,全部不用離開你正在做的事。
四個產品裡它最小,但「小而美」本身就是一種產品觀。
關鍵決策:本地打包函式庫,而不是 CDN
擴充功能用了 Fuse.js(模糊搜尋)和 SheetJS(匯出 Excel)。一般網站會從 CDN 載這些,我選擇全部打包在本地。
原因很擴充功能:它必須離線能用、必須快、而且不能有隱私外洩。從 CDN 拉一個檔案,就是一次網路延遲加一次「你載了什麼被誰看到」。本地打包之後,啟動器的回應時間壓在 0.1 秒以內,而且 SheetJS 只有在你真的按匯出時才載入,不用的人不必背這個包袱。
關鍵決策:虛擬列表 + 120ms 防抖
有些人裝了上百個擴充功能。如果清單一次把一百多個 DOM 節點全畫出來,捲動就會卡。所以我只渲染畫面上看得到的那幾個(加一點緩衝),這叫虛擬列表。搜尋輸入則做了 120 毫秒的防抖——你打字很快時不會每一個鍵都重算一次,但又快到你感覺不出延遲。
這些都是「使用者永遠不會稱讚,但一出問題馬上會罵」的細節。做工具型產品,順不順往往就贏在這種地方。
關鍵決策:內容腳本偵測頁面亮度,自動切主題
我放了一個跑在所有頁面上的內容腳本,去偵測當前網頁的亮度,回報符合 WCAG 的亮度資料,啟動器就自動在亮 / 暗主題間切換。使用者不用手動切,但想切也切得動。這是那種「多花一點力氣,換使用者一輩子不用操心」的設計。
AI 怎麼用
一樣,產品裡沒有 AI 功能。AI 幫的是「做出來」:Manifest V3 的樣板、Chrome 的 Management API 怎麼呼叫、還有最無聊但最花時間的——12 種語言的 i18n。zh_TW、zh_CN、en、ja、ko、es、fr、de、it、pt、ru、ar,每一個都要一份 messages.json。這種結構化、重複、又不能出錯的苦工,正是 AI 最該接手的活。
現況與投入
v1.0.0,準備上架 Chrome Web Store,隱私政策、五張商店截圖、上架文案都備好了,還有一個 Astro 做的 landing page。從第一版到打磨成能上架,斷斷續續跨了大半年。功能其實不多,真正花時間的是把鍵盤操作和無障礙(完整的 ARIA:combobox、listbox、tablist、dialog)做順。
踩過的坑
- 鍵盤操作的 UX 反覆改了好幾輪。 Enter 到底是「開關」還是「釘選」、Shift+Enter 又是什麼,早期很混亂,改了好幾次才定案。鍵盤優先聽起來很極客,但要做到直覺其實很難。
- 中文語系的編碼 bug。 設定畫面的 CJK 文字一度亂碼,修掉才發現多語系不是「翻譯完就好」,編碼、字型、排版每個環節都可能出事。
- 後來補了 Gmail 式的 undo。 開關、釘選之後跳一個七秒的 toast 帶「復原」,避免誤觸。這是用了才知道要加的東西——第一版沒有,被自己誤觸幾次後才補上。
產品四:Android AutoLaunch — 排程自動開 App
概述
| 項目 | 內容 |
|---|---|
| 類型 | Android App(API 26+) |
| 技術棧 | Kotlin + MVVM + Room + WorkManager |
| 狀態 | v2.4.0,Google Play 封閉測試中 |
| 開發時間 | 2025/3 首發,15 個月 9 個版本 |
| 營收模式 | 無(免費、無廣告、無內購) |

🔗 前往網站:autolaunch.bobochen.dev ↗
最後一個,也是我離舒適圈最遠的一個。AutoLaunch 讓你排程「在某個時間自動打開某個 App 或網址」——每天早上自動開新聞、上班時間自動開打卡頁、開會前自動開會議連結。設定一次,時間到它自己開。
我不是 Android 開發者。這個產品幾乎每一個技術決策,背後都是在跟 Android 作業系統的限制打架。
關鍵決策:AlarmManager 精確鬧鐘,而不是 JobScheduler / FCM
「在指定時間做一件事」,Android 有好幾個機制,但只有一個真的適合。
| 需求 | JobScheduler | FCM 推播 | AlarmManager 精確鬧鐘 |
|---|---|---|---|
| 分鐘級精準 | ✗(批次視窗) | ✗(不保證) | ✓(指定時刻) |
| 免後端 | ✓ | ✗(要伺服器) | ✓(純本地) |
| 適合的場景 | 省電批次任務 | 推播通知 | 「9:15 一定要開」 |
使用者要的是「9:15 就是 9:15」,不是「大概九點多的某個批次視窗」。JobScheduler 為了省電會把工作攢成一批,FCM 是拿來推通知的、不保證時間。只有 AlarmManager 的 setExactAndAllowWhileIdle() 能給到分鐘級的準。代價是要跟系統要 SCHEDULE_EXACT_ALARM 這個很敏感的權限——這個坑後面講。
關鍵決策(也是最好的一場戰役):用 overlay 繞過背景啟動封鎖
這是整個產品最硬、也最值得講的一段。
Android 10 之後,系統會默默擋掉從背景發起的 startActivity()——這叫 Background Activity Launch(BAL)封鎖。也就是說:鬧鐘時間到了、我的程式碼確實跑了、也確實呼叫了「打開那個 App」,但系統一聲不吭把它丟掉。使用者看到的是「什麼都沒發生」,而且沒有任何錯誤。這種 bug 最難抓,因為它不報錯。
解法是:持有 SYSTEM_ALERT_WINDOW(懸浮視窗)權限的 App,系統會網開一面,允許它繞過 BAL。所以我用一個 overlay 視窗來發起啟動。但更重要的是後面這個原則——
萬一使用者沒給懸浮視窗權限呢?我不讓它默默失敗,而是降級成一個高優先級通知,讓你點一下就開。
這是我從這個產品學到最重要的一課,值得單獨拉出來:
在跟平台限制打架時,誠實的失敗永遠好過安靜的失敗。寧可跳一個通知讓使用者多點一下,也不要讓他以為排程壞了、卻連為什麼都不知道。使用者能原諒「多一步」,不能原諒「不知道發生什麼事」。
關鍵決策:AlarmManager 之外,再用 WorkManager 補一層
光有鬧鐘不夠。Android 的 Doze 模式和 App 待命會殺掉你的行程,鬧鐘就沒了。所以我還掛了 WorkManager 做「開機後重新註冊所有排程」和「定期健康檢查」。開機廣播 + WorkManager 雙保險,才能讓排程在重開機、行程被殺之後還活著。這種「防禦性」的工,在手機這種你完全控制不了的環境裡是必修。
AI 怎麼用
產品裡沒有 AI。但這個產品是「AI 讓一個人敢跨到不熟領域」最極端的例子——我上一次認真寫 Android 是很久以前的事,Kotlin、AlarmManager 的精確鬧鐘、Accessibility Service、BAL 這一整套現代 Android 的眉眉角角,我幾乎是重新學。AI 幫我把「這個 API 在新版 Android 上為什麼行為變了」講清楚,也幫我產了 Play 商店的多語系文案和行銷素材。
沒有 AI,我大概不會為了一個 side project 去啃這麼多 Android 系統文件。這件事本身就是重點。
現況與投入
v1.0.0 在 2025 年 3 月首發,到 v2.4.0(2026 年 6 月)跨了 15 個月、9 個版本,目前在 Google Play 封閉測試。有意思的是節奏的變化:越到後面,時間越不是花在加功能,而是花在跟 Android 的背景限制打架。 v2.4.0 整版幾乎都在做「讓背景啟動可靠地成功」這一件事——上面那場 BAL 的仗。
踩過的坑
- BAL 封鎖(前面那場仗)。 最難的一個,因為它不報錯,你只能靠使用者回報「時間到了但沒開」去逆推。
- 精確鬧鐘權限很不可預測。
SCHEDULE_EXACT_ALARM在新版 Android 上使用者常常不給或事後收回,一收回就退化成不精確的排程,時間就會飄。只能偵測權限狀態、調整策略,並在引導頁老實解釋為什麼需要它。 - 模擬器會在權限對話框上崩潰。 某些權限請求(像電池最佳化)會讓模擬器的 System UI 直接掛掉,我得寫一個偵測「現在是不是跑在模擬器上」的 helper 去跳過。開發體驗的坑也是坑。
- 上架合規比想像中麻煩。 為了過 Play 商店審查,我把
QUERY_ALL_PACKAGES這個太廣的權限從 manifest 拿掉,改成只查得到「可啟動的 App」。跟商店政策打交道,本身就是一份工。
四個產品的共同模式
四個產品長得完全不一樣,但擺在一起看,有幾個反覆出現的模式。
模式 1:每個都從自己的一個癢處開始
- TaxMap-TW:我好奇「到底哪個里最有錢」
- TypeLate:我討厭打字
- Extension Jetpack:我裝了太多擴充功能,開關很煩
- AutoLaunch:我懶得每天手動開同一批 App
沒有一個是「我覺得市場有個缺口」開始的,全都是「我自己被這件事煩到了」。搔自己的癢有個好處:你就是第一個使用者,你永遠知道下一步該做什麼,因為那個痛是真的。
模式 2:技術棧跟著問題走,不是跟著舒適圈走
這四個產品用了四套幾乎沒交集的技術:Astro 的資料網站、Rust/Tauri 的桌面 App、Manifest V3 的擴充功能、Kotlin 的 Android App。
這看起來跟第 3 章講的「統一技術棧、最大化複用」矛盾。但其實不然——第 3 章那條原則是給「有正職、求快、求複用」的情境用的。而這四個 side project 有一個共同的隱藏目的:練功。 我想學 Rust,就用 Tauri 做 TypeLate;我想重拾 Android,就用 Kotlin 做 AutoLaunch。這時候「不能複用舊知識」不是成本,是我要的東西。
所以與其說矛盾,不如說這四個產品剛好是第 3 章那個「例外」的活教材:求複用時統一,求成長時發散。 你得先分清楚自己這次要哪一個。
模式 3:AI 最大的價值,是讓一個人敢跨到不熟的領域
這是我做完這四個產品最深的體會,也跟很多人講「AI 幫你寫 code」的重點不太一樣。
四個產品裡,只有 TypeLate 真的把 AI 變成功能。其他三個,AI 一行都沒進到產品裡。但 AI 在每一個產品都做了同一件事:當我的陪練,讓我敢碰我不熟的技術。 geospatial 工具鏈、Rust、現代 Android 系統限制——這些以前會讓我卻步的東西,因為有一個隨叫隨到、會解釋、會除錯的夥伴,門檻低到我願意在下班時間去試。
對一個人來說,這比「幫我把 code 打完」重要得多。它擴張的不是打字速度,是我敢做的事的邊界。
模式 4:先 ship,再靠版本號長大
四個產品沒有一個是「做完」才上線的:
- TaxMap-TW:先上一部分縣市,後來才補齊、才接每月自動更新
- TypeLate:從 v1.0 一路推到 v1.6.2,6 個版本
- Extension Jetpack:核心能用就開始打磨上架細節
- AutoLaunch:從 v1.0 到 v2.4,9 個版本,越後面越硬
先 ship,再完美。這是第 1 章 Solo Builder 宣言的核心,也是我每個產品都遵循的。真實的版本號,就是「有在動」最好的證據。
但我得把最誠實的一句話放在這裡:這四個產品,沒有一個賺到錢。 它們是免費、開源、搔自己癢處的作品;AutoLaunch 還在封測、Extension Jetpack 還沒正式上架,我手上也沒有什麼亮眼的下載數字可以秀給你看。
所以如果你把這四個模式當成「照做就會成功」的公式,那就誤讀了。這是 n=1,而且是我回頭看才整理出來的事後敘事,倖存者偏誤的味道很重——照這樣做卻沒做成的人有多少,我不知道,因為他們不會寫這種文章。把它當成「一個人這樣安排還算順手」的紀錄,不是保證。「做出來、ship 出去」跟「賺到錢」是兩件事,這一章談的是前者;後者,前面的章節談過,而且比這難得多。
我犯過的錯 & 如果重來一次
錯誤 1:低估了「上架」本身的工程量
我一直以為難的是把功能寫出來。實際上,「把它送到使用者手上」才是隱形的大魔王——TypeLate 的簽章與 macOS 權限、AutoLaunch 的 Play 商店合規、Extension Jetpack 的隱私政策與商店素材。這些不是「功能」,卻能吃掉你以為快做完之後的一大半時間。下次估時間,我會把「上架」當成一個獨立的、不小的階段來排。
錯誤 2:真正的敵人是平台限制,不是我的程式碼
macOS 的權限快取、Android 的 BAL 封鎖和 Doze、Chrome 的 Manifest V3 限制——這四個產品最難的坑,全都不是「我 code 寫錯」,而是「作業系統就是不讓你這樣做」。跟 OS 打架是做原生 App 的日常,我一開始完全沒把這塊算進成本裡。
錯誤 3:四個都沒想清楚「這是練功還是要賺錢」
我很享受做這四個東西,但如果重來,我會更早對每一個問一句:這是拿來練技術的,還是要它養活自己的?兩種都很好,但目標不同,該做的取捨就不同——練功可以放縱地用不熟的技術棧,要賺錢就得回到第 2 章那套驗證流程。我把這四個都當練功做,結果就是四個很有趣、但沒有商業引擎的作品。這不是錯,但我當初該更清醒地選。
錯誤 4:多語系做太早、也做太滿
Extension Jetpack 一口氣上了 12 種語言、AutoLaunch 也鋪了四語。多語系聽起來很國際化,但在還沒確定有人要用之前,維護 12 份翻譯是一種很甜美的拖延。如果重來,我會先用一兩種語言驗證有沒有人在乎,再決定要不要鋪滿。
如果重來一次的優先順序
- 先確認「這次要練功還是要賺錢」,再選技術棧
- 把「上架 / 送到使用者手上」當成一個獨立階段排進時間,不要低估它
- 原生平台的限制先查清楚(背景執行、權限、商店政策),別等使用者回報「沒反應」才發現
- 多語系、進階功能往後放,先讓核心跑起來、先確認有人要
- 想賺錢的產品,回第 2 章走一次驗證,別用「我覺得很酷」代替「有人願意付」
本章重點回顧
- 🗺️ 四個產品刻意選得很不一樣——資料網站、桌面 App、Chrome 擴充、Android App——四種平台、四套技術棧
- 🧩 技術棧跟著問題與目的走:求複用時統一,求成長(練功)時故意發散
- 🤖 AI 在四個產品最大的價值不是變成功能,而是讓一個人敢跨到 Rust、Kotlin、geospatial 這些不熟的領域
- 🧱 最硬的坑幾乎都不是自己的 code,而是平台限制(macOS 權限、Android BAL/Doze、Manifest V3)
- 🚀 每個產品都是「先 ship 再靠版本號長大」,用真實的版本歷史證明「有在動」
- 💸 誠實的結尾:這四個都沒賺到錢——「做出來、ship 出去」和「賺到錢」是兩件事,這章談的是前者
下一步
看完了真實案例,接下來是全書的最後一章。
我為你準備了一份 Solo Builder Checklist——從點子驗證到上線營運,一份可操作的檢查清單。不管你的產品在哪個階段,都可以用這份清單來檢查你有沒有遺漏什麼關鍵步驟。