※ この記事はハイボール6杯目から書き始めています。
半年に一回くらい書いているやつです。いつもはNotionですが、せっかくなのでここで。
少し前に書いたこの記事でも少し言及しましたが、最近の僕の個人開発は
不特定多数に公開する→クラウド
自分・身内用→おうちKubernetes
という風に二分化しています。そんな訳で、この記事も2章に分けて書いていきます。
前提として、Webアプリに絞って書きます。ネイティブアプリを作らない訳じゃないですが、僕は個人開発では自分でも使えるものを作ることを大前提にしているので、Apple端末に囲まれた僕はSwift以外を使う理由がないためです。
また、説明なしに静的型付け言語、OpenAPIやGraphQLにおけるコードファーストなライブラリ、及びReactを優先して選択します。この辺の理由はまたその内書きますが、一旦飲み込んでください。
不特定多数に公開するアプリの技術選定
不特定多数に公開するアプリを開発するモチベーションとしては大きく2つあります。
あわよくば多くの人に使ってもらって収益化したい
要するにバズってほしいということ
自分が使いたかったアプリを作ったついでに誰でも使えるようにしたい
どちらの場合にも、サーバーレス系のサービスを使うのがぴったりです。ほとんどのサーバーレス系のサービスには
ユーザー数が少なければ無料
ユーザー数が増えても(金され払えば)ほぼ設定なしでオートスケール
という特徴があるため、バズってほしい場合には後者の特徴がハマり、自分が使いたかったアプリを共有する場合(積極的に宣伝しない場合)には前者の特徴がハマります。
サーバーレス系のサービスを使うことは決まったとして、次に考えることは、フロントエンドとサーバーサイドを分けるかどうかです。つまり、いわゆるフルスタックフレームワークを使うかどうかです。それぞれの場合について考えてみます。
フルスタックフレームワークを使う場合
Reactを型安全に使いたいので、選択肢はReactのラッパー系のフレームワークに限られます。Gatsbyは、特にサーバー側の機能が不足しているため、現実的な選択肢としてはNext.js+VercelかRemix+Cloudflare Pagesになると思います。Next.jsは「デフォルトで良い感じに動く」という特徴がある一方、Remixは細かいところまでカスタマイズできる上に色々な実行環境で動くことがメリットになると思います。個人開発ではカスタマイズ性よりも勝手に良い感じに動いてくれることの方がメリットになることが多いため、Next.jsがお勧めです。
フルスタックフレームワークを使わない場合
1アプリでサーバーを2台以上持つことは、個人規模の開発ではコストの有意な増加に繋がります。つまり、フロントエンド側は静的エクスポートして、Cloudflare Pages等のほぼ無料なサービスでホストする必要があります。React系のフレームワークであれば、ほとんど全て静的エクスポートに対応していると思いますが、SSRしない場合には機能を少なく抑えた上で開発時のHot Reloadやテストを高速化することに焦点を当てたフレームワークの方が開発体験は良くなると思います。という訳で、フロントエンドはVite + Reactが良いと思います。Gatsbyも静的エクスポートに特化しているように見えますが、Hot Reloadやテストの速度は数段Vite + Reactに劣るため、ブログやHPでない限りは採用する理由はないと思います。
サーバーサイドは「ユーザー数が少なければ無料」を重視するならAWS Lambda、「ユーザー数が増えてもオートスケール」を重視するならコスパ面でCloud Runが良いと思います。とはいえ、どれもコンテナランタイムが使えるので、事実上の制約はほとんどありません。
どのサービスを使うかを考えたら、サーバーサイド言語について考えます。クライアント-サーバー間の通信の型安全性に関してはRESTful APIでは openapi-typescript (https://github.com/drwpow/openapi-typescript) 、GraphQLでは nitrogql (https://github.com/uhyo/nitrogql) 等の登場によりほとんど気にする必要はなくなったため、文法とCPU/メモリ効率で考えるのが良いと思います。
文法はともかく、CPU/メモリ効率はダイレクトにコストに関わってくるため、優先的に考えた方が良いと思います。この辺の話は、プログラミング言語ごとのエネルギー効率の話 (https://www.sciencedirect.com/science/article/abs/pii/S0167642321000022) が有名で度々引用されますが、プログラムの書き方や実行環境にも依るので鵜呑みにしてはいけないはことは確かです。とはいえ、Webアプリ開発向けのライブラリが揃っている言語のうち、RustはCPU効率に優れ、Goはメモリ効率に優れるというのは直感にも一致するためこの記事では鵜呑みにすることにします。サーバーレス系のサービスを使う場合にはどちらかというとCPU効率の方が大事な場面が多い(実行時間がそのまま料金になることが多い)ため、この記事ではフルスタックフレームワークを使わない場合にはRustをサーバーサイドに使うべきであると断言したいと思います。Rustのフレームワークですが、有名どころであれば正直どれを使っても書き心地に大きな違いはないため、何でも大丈夫です。強いて言えば個人開発規模ではOpenAPI+コードファーストの方が書き心地が良い場合が多く、その場合のライブラリとしては utopia (https://github.com/juhaku/utoipa) しか現実的な選択肢はないため、utopiaのexamplesに載っているフレームワークを選択した方が簡単かもしれません。
ここまでの話をまとめると、不特定多数に公開するアプリは
Next.js + Vercel
Vite(React) + Rust
のどちらかになります。収益や機能面が目的なら明らかに上前者が良いですし、アプリのリリースまでの期間は短くなりやすいです。一方で、開発の面白い部分はフロントエンドとサーバーサイドを分けた後者の方が得やすいですし、大きくスケールしてもそんなにコストは大きくならないことが多いです。
ニッチなアプリや、無償で色んな人に使って欲しい場合にはNext.js + Vercel、多数の人に使ってもらってあわよくば収益を得たい場合にはVite(React) + Rustという感じで使い分けることになると思います。
ちなみにVercel Postgresのデータベースは最寄りでもシンガポールになるため、現実的にはPlanet ScaleやTiDBになると思います。どちらもMySQL互換のため一般には困ることは少ないでしょうが、PostgreSQL特有の機能が必要な場合にはKAGOYAのデータベースプラン等の国内の格安DBを使うことになると思います。
自分・身内用アプリの技術選定
冒頭に書いた通り、自分・身内用のアプリは僕の場合はおうちKubernetesで運用しています。一般的にも長期間の運用を想定するならおうちKubernetesが(1台のサーバーを購入するとしても)最もコスパに優れていると信じています。
そんな訳で、おうちKubernetesを前提に議論します。おうちKubernetesの場合、コストはサーバー機代+電気代になりますが、サーバー機は基本的に長持ちすると考えて電気代について考えます。電気代となると、前述したプログラミング言語ごとのエネルギー効率の論文を参考にしてRustを推して終わらせたいですが、そんな訳には行きません。おうちサーバー機が十分なスペックを持っていれば確かにRustで良いかもしれません。
とはいえ、おうちサーバーを増設するのはそこそこのリスクなので、CPUとメモリのどちらも頭打ちしないように技術選定したいところです。CPU効率は、現代的な言語の中ではRustが飛び抜けて良いですが、メモリ効率ではGoの方が良いです。JS/TSも悪く無いですが、PHP/Python/Rubyあたりは数段エネルギー効率は落ちます。CPUもメモリも頭打ちしないようにすると、やはりRust/Go/TypeScriptから選択することになります。フロントエンドはほぼ無償でクラウド上で運用できるので気にしないことにします。電気代のことを考えると、フルスタックフレームワークは若干劣るのでNext.js等のことは考えません(自動的にフロントエンドはVite (React)になります)。
具体的にはCPUが足りなくてメモリが余っているならRust, 逆ならGoやTypeScriptをサーバーサイドの言語として採用すべきです。これはサーバー機の選び方にも依るので何とも言えませんが、どちらかというとRustを多めに採用した方がコストは抑えやすい傾向にあると思います。次点でGoです。その次にTypeScriptですが、ライブラリの充実度具合的に開発効率は最も良いため、機能の継ぎ足しをやる予定が全くなく、短期的な運用を前提としているのであればTypeScriptが一番良い可能性もあります。TypeScriptを書く場合には経験的にはBunが最もCPU/メモリ効率に優れています。
そんな訳で、自分・身内用アプリでは
Rust + Vite (React)
Go + Vite (React)
Bun + Vite (React)
のいずれかを使うことになります。
まとめ
2024年は、収益化狙いなら
Next.js + Vercel
Vite(React) + Rust
自分・身内用なら
Rust + Vite (React)
Go + Vite (React)
Bun + Vite (React)
という感じで個人開発するのがベストです。