Enam bulan membangun Bookverse, sendirian

Ada versi romantis dari membangun perangkat lunak sendirian, di mana kamu memiliki meja yang rapi, sebuah espresso, dan kamu merilis sesuatu yang dicintai orang sebelum jam makan siang. Versi yang benar-benar saya jalani selama enam bulan terakhir lebih mirip “menulis konfigurasi Nginx yang sama sebanyak empat kali karena edge case ketujuh baru saja menggigitmu.”

Ini adalah sebuah refleksi — bukan daftar centang hal-hal yang sudah dirilis, bukan tutorial. Hanya catatan dari enam bulan perjalanan.

Mengapa saya memulai

Saya sudah memakai aplikasi belajar bahasa secara tidak menentu selama bertahun-tahun dan menyadari sesuatu yang spesifik: saya bisa menyelesaikan streak 30 hari di aplikasi gamifikasi populer namun tetap tidak bisa membaca satu paragraf teks asli. Loop umpan baliknya rapat, gamifikasinya mulus, tetapi satuan kemajuannya adalah sebuah kalimat, kadang sebuah kata. Dan membaca bahasa — benar-benar membacanya — terjadi pada level halaman.

Saya menginginkan aplikasi yang memperlakukan buku teks seperti buku teks. Buka bab satu. Baca. Dengarkan. Ucapkan kembali. Pelajari apa yang melekat. Besok, bab dua.

Bentuk produk itu sudah jelas sejak hari pertama. Jebakannya adalah “bentuk jelas sejak hari pertama” hanya bertanggung jawab atas mungkin 5% dari membangun perangkat lunak. 95% sisanya adalah bagian tengah yang tidak glamor.

Bagian tengah yang tidak glamor

Daftar tak lengkap dari hal-hal yang saya lakukan kuartal ini yang tidak ada di catatan rilis mana pun:

  • Mengganti nama seluruh pohon jalur monorepo dari app_v54_01 menjadi bookverse (dan mengganti namanya lagi ketika saya ingin garis bawah di nama unit systemd).
  • Menulis empat versi konfigurasi Terraform untuk vhost Nginx sebelum menemukan bahwa trigger null_resource perlu menyertakan hash dari template yang sudah dirender, bukan hanya variabel input.
  • Menghabiskan seminggu melacak mengapa sebuah nilai env EXPO_PUBLIC_* ter-resolve menjadi string kosong di bundle web tetapi berjalan baik di iOS. (preset-expo milik Babel melewati inlining untuk node_modules. Fungsi factory, bukan variabel env, di paket yang sudah dipublikasikan.)
  • Merefaktor 17 pemanggil sebuah helper URL API karena saya salah memusatkannya pada percobaan pertama.

Tidak satu pun dari ini akan masuk ke postingan pemasaran tentang aplikasi itu. Semuanya adalah pekerjaan yang sesungguhnya.

Hal yang tidak diperingatkan siapa pun tentang pengembangan solo adalah tidak ada orang yang menyerap separuh yang membosankan. Kamu tidak bisa bilang “tim platform menangani deploy” karena kamulah tim platform itu. Kamu memakai setiap topi dengan buruk sampai kamu memakainya cukup lama untuk memakainya dengan baik.

Lubang kelinci pengenalan suara

Episode paling instruktif dalam enam bulan terakhir adalah membuat latihan berbicara berfungsi di ponsel di Tiongkok.

Rencananya: ketuk sebuah baris, dengar penutur asli mengucapkannya, ketuk lagi, rekam dirimu sendiri, lihat seberapa dekat hasilmu. Pengenalan suara seluler standar — expo-speech-recognition di iOS, layanan sistem di Android, selesai.

Kenyataannya: sebagian besar audiens target memakai ponsel Lenovo Motorola dengan varian OS versi Tiongkok (overlay gmsconfig.china), yang membuang Google Mobile Services sepenuhnya. Tidak ada speech-to-text sistem. Aplikasi berjalan sempurna di emulator. Di sebuah Moto XT2507 di Beijing, ia crash tanpa suara.

Perbaikannya memakan waktu sekitar tiga minggu:

  1. Membangun pola adapter agar aplikasi bisa menukar backend suara per platform — pengenalan sistem di mana tersedia, transkripsi cloud sebagai fallback.
  2. Menambahkan backend cloud bergaya Whisper (qwen3-asr-flash dari Alibaba via DashScope, karena perangkat versi Tiongkok bisa menjangkaunya tanpa VPN).
  3. Menyetel deteksi aktivitas suara agar rekaman berhenti otomatis ketika kamu selesai bicara. (Ambang -25 dBFS, jendela hening 600ms, dihaluskan atas lima sampel — setiap kombinasi lain entah memotongmu di tengah kata atau tidak pernah berhenti sama sekali.)
  4. Beralih dari unggahan FormData React Native ke uploadAsync milik expo-file-system, karena FormData RN tidak stabil dengan blob audio di perangkat yang sama.

Separuh dari empat poin itu adalah lebih banyak kode daripada yang saya tulis dalam seminggu biasa. Tidak satu pun adalah “sebuah fitur.” Semuanya perlu agar fitur itu ada bagi orang-orang yang membutuhkannya.

Pelajarannya — terulang kira-kira setiap dua minggu — adalah bahwa bagian yang sulit jarang merupakan bagian yang kamu kira akan sulit. Saya menganggarkan satu hari untuk pengenalan suara. Butuh dua puluh hari.

Disiplin menyelesaikan

Godaan ketika membangun sendirian adalah mengejar yang baru dan berkilau. Fitur baru itu menarik. Penyesuaian ke-47 pada alur yang sudah ada tidak. Jadi kamu menumpuk fitur, yang tidak satu pun benar-benar selesai, dan produk terasa seperti kuburan bangunan setengah jadi.

Disiplin yang terus saya pelajari ulang: selesaikan satu hal dengan benar sebelum memulai yang berikutnya. Mandarin dulu. Buat Mandarin benar-benar bagus. Lalu Korea. Lalu Inggris. Platform ini dibangun untuk menyampaikan kursus terstruktur — tetapi kursus pertama harus menjadi yang unggulan, yang benar-benar bisa diselesaikan oleh seorang pembelajar.

Kursus Korea yang direncanakan dan baru 5% jadi tidak membantu siapa pun. Kursus Mandarin yang selesai, yang bisa dibaca seseorang dari awal sampai akhir, adalah produk yang nyata.

Begitu pula dengan fitur. Latihan berbicara ada di roadmap selama tiga bulan sebelum dirilis. Ia dirilis terlambat, tetapi dirilis dengan benar — menangani kasus wilayah Tiongkok adalah elemen penyangga agar ia dapat digunakan, bukan detail pemolesan yang bisa ditunda.

Apa yang akan saya katakan pada diri saya di bulan November

Tiga hal, andai saya bisa mengirim kartu pos kembali ke versi diri saya yang memulai ini.

Berhenti mengganti nama. Nama adalah hal yang wajar salah di hari pertama. Mengganti nama lagi lebih banyak menguras daripada manfaatnya dalam sebagian besar kasus. (Saya sudah melakukan ini tepat empat kali sekarang.)

Beli buku terstruktur. Saya menghabiskan berminggu-minggu memantul di antara daftar kosakata dari forum. Standar HSK 3.0 adalah dokumen terbit yang nyata. Membeli buku terstruktur dan mengikutinya lebih cepat daripada merekayasa balik apa yang mereka cakup.

Audiensnya sabar. Saya terus berpikir saya harus merilis cepat atau orang akan kehilangan minat. Sebaliknyalah yang benar: pembelajar bahasa menurut definisinya sabar — mereka sudah berkomitmen pada satu tahun latihan. Mereka tidak butuh demo di hari ketiga. Mereka butuh sesuatu yang berfungsi di hari ketiga ratus.

Apa selanjutnya

Mandarin terus tumbuh — Band 1 dan Band 2 sudah aktif, Band 3 sedang diaudit sekarang. Penyusunan konten kursus Korea dimulai setelah Mandarin Band 3 dirilis. Sisi platform lebih tenang dibanding enam bulan lalu, yang berarti lebih banyak waktu masuk ke konten pembelajaran yang sebenarnya — yang memang seharusnya menjadi tempatnya.

Jika kamu memakai Bookverse: terima kasih. Jika belum: bukalah sebuah bab suatu saat. Yang pertama gratis.

← Semua postingan