📖

5年かけて作ったウェブアプリを Hacker News に投稿し、最初の1ドルを得た話

2022/02/12に公開約7,000字

これは5年かけて JavaScript の技術スタックの間をうろつき、無駄な時間を過ごし、迷い、そしてなんとかローンチにこぎつけた体験の記録です。

自己紹介

初めまして。私は小さなモバイルアプリ開発会社を運営しているエンジニアです。

プログラミングを始めたのと同じくらいのときから、趣味で作曲活動をしています。

今日の作曲は DAW と呼ばれる大型のソフトウェアを利用することがスタンダードになっています。しかしたくさんのプラグインをマシンにインストールしなければならないことや、すぐに立ち上がる作曲ソフトが無いことにフラストレーションを覚え、軽量な MIDI シーケンサーアプリを好んで使っていました。

しかしそれらの多くは Windows2000 の時代から存在し、アップデートされず、その上 Windows 10 以降 MIDI の再生はまともにサポートされなくなりました。

その問題を解決するため、私はミニマムで超軽量、立ち上げたらすぐ使える作曲アプリの開発をはじめました。

2014年

コードを書き始めたのが2014年11月のことです。まず私は、誰もがそうするように、GUIフレームワークの実装を始めました。これは今思うと、明らかに失敗、いやプロジェクトの長期化の兆候です。

しかしそれでも、C++ で実装したオーディオエンジン、GUIフレームワークは順調に構築され始めました。ピアノロールが表示され、音が鳴らせます。フォントもレンダリングされ、Mac でビルドすることもできます。

4ヶ月が経過した2015年3月に、まだ私はスクロールバーを実装していました。あなたがどれだけ腕に覚えがあったとしても、GUIフレームワークから開発を始めることだけはやめたほうがいいでしょう。

2015年

そして2015年5月、私は当時爆発的に流行していた「Electron」に目をつけました。Slack で使われているテクノロジーとして、羨望の眼差しを集めていました。
このころ、会社ではまだ HipChat を使っていたかもしれません。HipChat です。覚えていますか?

そう、もうおわかりでしょう。Electron と CoffeeScript で行こう。この技術スタックで間違いないという確信がありました。
まだ Webpack はそれほど有名ではありません。ライブラリを js ファイルでダウンロードしていた時代、CoffeeScript ほどクールなテクノロジーはありませんでした。
(いまだに私は CoffeeScript の"閉包"のファンです。)

coffee-react というライブラリを使い、React.createClass でコンポーネントを書いていました。それほど悪くはないですね。

この頃はまだ音を Audio クラスの生成により再生していたため、パフォーマンスはあまりよくありませんでした。そして当然、UI は見るからに未完成です。

2016年

もう3年目、これではいつまでも完成しないという危機感から、ようやくコンセプトを定めました。当時の README.md を見てみましょう。

音源選びやエフェクトの調整に気を取られずに作曲に集中できるアプリにする

素晴らしいですね。これは今日も守られています。

そしてコードを見てみましょう。主な技術スタックは相変わらず CoffeeScript ですが、UI フレームワークを React から Riot.js に変更しました。
これは振り返ってみると、明らかに最大の時間のロスの原因です。(名誉のために書きますが、Riot.js はとても素晴らしいライブラリです。)

Riot.js、知っていますか?今で言う Vue みたいなものです。私はテンプレートの .tag ファイルを書きまくりました。
Babel と Mocha、ESLint を導入し、ライブラリも npm で追加しています。意外とイケてると思いませんか。リポジトリを作ったのもこの頃です。

https://github.com/ryohey/signal

ここで一つ大きな寄り道があるとすれば、ステート管理ライブラリを作ったことです。

そうです。誰もが、オリジナルのステート管理ライブラリを作ります。私も例外ではありません。これは思いつきで作ったので、気にしないでください。

https://github.com/ryohey/shinjuku

そしていよいよ時が来ました。「ES6」です。

アロー関数、map, filter、CoffeeScript のクールな機能が JavaScript に来ました。私はすべてのコードベースを CoffeeScript から ES6 に書き換えました。新しい標準ほどクールなものはありません。

そして半年ほど Riot.js での実装は順調に進行しました。アプリケーションとしての形はほぼできています。
コードのモジュール化を進め、限りなくクリーンなコードベースへと進化してきました。

はい。そうです。心の声がしました。「Riot.js をやめて React に乗り換えよう」
この考え自体は悪くありません。2022年でも React は流行っているのですから。しかし、プロジェクトとしては最もやってはいけない行為でした。なぜなら、2021年までアプリを公開できなかったのですから。

フロントエンドエンジニアならおわかりでしょうが、このあと、仕事は山積みになりました。

  • JSX の導入
  • クラスベースのコンポーネントから関数コンポーネントへの変更
  • HcC の導入

しかし、実に2ヶ月程度の集中作業により、意外にも React への乗り換えはスムーズに済みました。また、音声周りの実装もどんどん進み、アプリのアーキテクチャとしてはほぼ今と変わらないような形になりました。

2017年

ここからはひたすら実装です。画面レイアウトを大幅に変更したり、マウスで音符をドラッグするときの処理をリファクタリングしたり、細かい挙動の調整に明け暮れていました。
もちろん色にもこだわっています。テーマを切り替える機能すら存在していました。
この頃、アプリのクオリティは実用レベルに達していました。なぜリリースしてしまわなかったんでしょうか。今なら、今すぐリリースしろとアドバイスするでしょう。

しかしリリースしない理由がやってきました。MobX というステート管理ライブラリの導入と、型検査システム Flow の導入です。自前の Store は大幅な (そしてよりクールな形への) 書き直しを迫られました。

2018年

超巨大な変革がやってきました。「TypeScript」です。型安全でない大量の JavaScript コードで塗り固められた Web アプリを公開すべきでしょうか?当然Noです(当時の私からしてみれば)。

そう、TypeScript で書き直します。自作のライブラリを含め、全てを TypeScript で書き直しました。
any を無くすことが 2018 年最大のミッションと言えるでしょう。

2019年

この年はあまりコードを書けませんでした。その代わり、やることが増えました。"Material-UI" の導入です。Bootstrap 以降、僕たちはクールな UI キットに翻弄され続けてるのです。
(2022年の僕は今、Unstyled UI Library が非常にクールだと思っていますが、危険な兆候でしょうか)

とにかく ButtonToolbar といった自前のコンポーネントを Material-UI のものに置き換えていきます。独自のコードが減って巨人の肩に乗った気持ちになれるのもまた、クールなことです。

この頃は UI に関してはほぼ完成形になりましたが、いざ本当に作曲に使おうとするとどうでしょうか。ピアノロールの動作が重いです。知っていますか?Reactでこういった音符みたいな大量の要素をレンダリングするもので、動作が軽いウェブアプリを作るのは非常に難しいことなんです。

こんな動作が重いアプリを公開できるわけがありません。私はあらゆるパフォーマンスの改善を行いました。

2020年

どうしてもピアノロールの動作が重いことが改善できずにいました。描画方式の歴史を知りたいですか?下に年表を書いておきます。

描画方式
2016.3 <div> タグでの描画
2016.4 <canvas> での描画
2016.5 EaselJS での描画
2016.8 React導入
2016.9 EaselJS をやめる
2020.6 react-pixi 導入
2021.3 react-pixi 廃止、WebGL を直接利用

そうです。2021年になるまで、この問題は解決されませんでした。アドバイス?たくさんのものを描画するなら、WebGLがおすすめですよ。

そしてステート管理ライブラリと React にもムーブメントがありました。"Hooks" の登場です。
もう HoC は古いのです。すべてを useXXX に書き換える時が来ました。でも知っていますか?2021年には MobX は hooks ではなく HoC を推奨しています。笑

あぁもう一つありました。.css はクールではありません。すべてを styled-components に書き換える時が来ました。

やることは山積みでしたが、着実にアプリの機能は充実してきました。いよいよ、ローンチの時が来ました。
ローンチして、Hacker News に投稿しよう。

リリース2日前

Hacker News に投稿することで、当然ウェブアプリはバズり、僕はこの5年分の労力に見合うものすごい脚光を浴びてしまうのでしょう。そうなると、マネタイズの方法が無いのがもったいないですね。
そこで GitHub Sponsors を申請しました。

GitHub Sponsors の申請ページにはチェックリストがあり、各種準備を行う。全部終わると申請ボタンが有効になり、申請することができます。
まず支払先の Stripe アカウントを作る必要がありました。免許証を取って送ったりとかやや面倒でしたが、15分くらいで承認されました。

そして米国の税金に関する書類などを記入。私は日本在住なのでこういった書類には慣れていません。項目は少ないが調べながら記入したので面倒でした。マイナンバーを記入しました。

最後に自分のプロフィールや Tier などを設定しました。自己紹介はさっと短めにして、Tier もとりあえず $1 だけにしてみました。GitHub に申請を送信すると、1時間くらいで承認されました。

また、README.md を英語に翻訳しました。

リリース直前

ランディングページを3時間ほどで作りました。最初からこのスピード感でやっていたら5年もかからなかったのにね。ランディングページには対応ブラウザやバグ報告のフォームを記載しました。

そしてデプロイです。さて、5年かけたウェブアプリですが、なんと一度もインターネットにデプロイしたことがありませんでした。"ウェブ"アプリなのにですよ。

どうやらクールらしいと聞いていた "Vercel" を使うことにしました。Vercel は本当にクールで、10分もあればデプロイが完了しました。

また、日本でもバズってしまうかもしれないので、アプリ自体の日本語ローカライズを行いました。

そして最後に Google Analytics のコードをコピペし、Show HN の準備が整いました。

初日

これが Hacker News への投稿です。

https://news.ycombinator.com/item?id=24599679

米国時間17時とかに投稿するといいらしいが、待てなかったので日本時間の夜に投稿しました。投稿した直後3ユーザーがアクセスしたので、スゴいと思いました。

しかし最初タイトルに Show HN: をつけ忘れていたのであとから変更しました。変更した直後からユーザー数が一時的に常時1くらいに落ちた。ありがたいことに、その後モデレータから反応があんまりないから後日またトップページに掲載するねっていうメールが来ました。(たぶん定型文だけど)

アクセスはモバイル7割、PC 3割だったので急いでランディングページをモバイル対応しました (CSS で media query でちょっと上書きするだけ)。

すぐに HN でコメントが5個くらいつきました。正直バズっているというほどではなかったけど、初めてもらった反応なのですごく嬉しかったです。

ずっと Google Analytics を眺めていました。アクセス地域が地球の回転に合わせて移動していて、世界中からアクセスされているのを見ることができました。

次の日

HN からは午前中に常時15アクセスくらい、午後は常時10アクセスくらいで推移しました。Twitter で告知すると、50Favくらいつきました。しばらくはアクセスが Twitter と HN 半々くらいでしたが、だんだん減っていって HN 経由が多くなっていきました。

HN でコメントに返事しまくったら 50point になってトップページの20位まで上がりました。数時間経ってコメントは増えないまま57ptまで上がりましたが、順位は23まで下がりました。

次の日の夜

常に13ユーザーがアクセスしていました。Twitter からのアクセスは無くなり、GitHub の issue に報告が1件きました。

次の次の日

Twitter の fav 数が 90 になり、GitHub の star 数が 99 になりました。

そして、GitHub Sponsor が1人つきました!たったの月1ドルですが、これは嬉しかった。

HN のトップページから消え、アクセス数は常時1, 2くらいに落ちました。

2022年

ローンチから1年が経ちました。月間ユーザー数は1万人に向かいゆっくりと増え続けています。

パフォーマンス改善は続いています。音声周りの処理をフルスクラッチで書き直し、大幅にパフォーマンスを改善することができました。

Star は 299 になり、GitHub Sponsors は2人に増えました。
また、Carbon というテック向けの広告を導入したことで、年間1万円くらいの収入になりました。
ユーザーが集まるチャットの Gitter はアクティブで、GitHub には時々 issue が立てられ、Contributor も現れました。
バズってはいないし、生活が変わるほどの何かは起きていないけど、僕は5年かけて作ったウェブアプリを (一応) 完成させ、最初の指先ほどの小さな栄光を得ることができました。

今後

ここまで書かなかったけど、実はこのアプリの目標は「多人数で作曲を行うためのシーケンサーアプリを開発する」で、まだコラボレーション機能はひとつも搭載されていません。
だから5年かかっても全然完成していないし、まだまだ道のりは遠いです。

でもローンチは偉大です。作曲しようと思ったときに、サッと開いてすぐ使えるウェブアプリはもうここにあります。みんなにとっては、この5年間まったく存在しませんでした。
とにかく目標を定め、ローンチに向かってまとめあげること。

作曲のオンラインコラボレーション

誰かがメロディだけを書いた曲を、他の誰かがコードを付けたり、あるいはまったく別のジャンルに派生させたり、しかもそれがウェブの画面ですべて見えたらクールだと思いませんか?
サクッと作った曲を埋め込みコードでブログに貼ったり、それを再利用して新しい曲を作ったり・・・
例えて言うと、CodePen の音楽版でしょうか。

それに、GitHub の Pull-Request みたいな機能で、一曲を複数人で作曲するなんてどうでしょうか。これこそ僕が何年も前からやりたかったことなんですが。

Webであることの利点を最大限活かして、作曲のコラボレーションを実現する。そんな構想のスタート地点にやっと立ちました。

仕事じゃなくて、趣味なんですけどね。

signal

完全オープンソースのオンライン作曲アプリ。何もインストールすることなく、すぐに作曲を始めることができます。

https://signal.vercel.app/

記事が面白かったら GitHub に Star してください。Sponsors も増えたら嬉しいです。

https://github.com/ryohey/signal

Discussion

ログインするとコメントできます