nun_game0

個人開発でNext.jsを選んだ理由と、正直な後悔

Next.js個人開発

このサイトはNext.js(App Router)で作っている。個人サイトにNext.jsを選んだのは正解だったのか。良かった点と後悔を正直に書く。

選んだ理由

Reactの知識がそのまま使える。仕事でReactを触ることがあるから、学習コストが低かった。新しいフレームワークを一から覚える余裕はなかったし、「仕事で使う技術の延長線上で個人開発をする」のが自分のスタイルに合っている。

週末に数時間しか取れない個人開発の時間で、フレームワークの基礎から学び直すのは現実的じゃない。Reactのコンポーネント設計やhooksの知識がそのまま活きるNext.jsなら、やりたいことに集中できる。

App Routerを試したかった。Next.js 13以降のApp RouterとReact Server Componentsは、発表された時から気になっていた。ただ、仕事のプロジェクトでいきなり採用するのはリスクがある。個人サイトなら壊れても誰にも怒られない。本番環境で新しい技術を試す場として、ちょうど良かった。

実際、App Routerの layout.tsx によるネストレイアウトの仕組みは、Pages Routerとはまったく考え方が違う。個人サイトで先に触れておいたおかげで、仕事でApp Routerの話が出た時にスムーズに議論できた。

情報量の多さ。Next.jsはユーザー数が多いから、困った時にGoogle検索すれば解決策が見つかる。Stack OverflowにもGitHub Issuesにも先人の知恵がある。マイナーなフレームワークだと「同じエラーに遭遇した人が誰もいない」みたいな状況になりがちで、そこで時間を溶かしたくなかった。

あと、Claude CodeやCopilotといったAIツールとの相性も決め手だった。Next.jsはトレーニングデータに大量のコード例が含まれているから、AIにコード生成させた時の精度が高い。これは地味に大きい。

良かった点

ファイルベースルーティングの手軽さapp/blog/[slug]/page.tsx を作るだけでルーティングが完成する。設定ファイルを書かなくていい。ブログ記事を追加する時も、ルーティングのことを一切考えなくていいのは快適だった。

ディレクトリ構造がそのままURLになるから、プロジェクトの見通しも良い。app/about/page.tsx/aboutapp/blog/page.tsx/blog。初見でもどのファイルがどのページに対応しているか一目でわかる。

静的生成の手軽さgenerateStaticParams で全ページを事前生成できる。ビルド時にHTMLが生成されるから、ランタイムのパフォーマンスが良い。ブログ記事は更新頻度が低いから、静的生成との相性が抜群だった。

具体的には、Markdownファイルをビルド時にJSONに変換して、そのJSONから静的ページを生成する流れにしている。ランタイムではファイルシステムに一切アクセスしない。この設計はCloudflare Workersにデプロイする上でも都合が良かった(Workersでは fs モジュールが使えないので)。

TypeScriptとの相性。型安全にコンポーネントを書ける。propsの型定義があるから、コンポーネント間のデータの受け渡しでバグが起きにくい。個人開発だとテストを書くのをサボりがちだけど、型チェックがあるだけでかなり安心感がある。

Next.jsの構成

後悔していること

オーバースペック感が否めない。個人サイトに App Router は正直やりすぎだった。Server Components、Streaming、Parallel Routes、Intercepting Routes。Next.jsが提供する機能のうち、自分が使っているのは全体の2割くらいだと思う。

静的なブログサイトなら、AstroやHugoの方がシンプルに作れた。Astroなんてコンテンツ特化のフレームワークだから、Markdownのブログを作るなら最適解に近い。Hugoはビルドが爆速で、100記事だろうが1000記事だろうが1秒かからずにビルドが終わる。

Next.jsは機能が豊富すぎて、個人サイトの規模には合わない。サッカーの試合にF1マシンで乗り込むような感じ。

ビルド時間の増加。ページ数が増えるとビルドが遅くなる。今は23記事で約40秒。まだ許容範囲だけど、100記事になったら2〜3分かかりそうな予感がある。Hugoなら100記事でも0.5秒で終わる世界なので、ここは明確に負けている。

next build の出力を見ていると、静的ページの生成よりもWebpackのバンドル処理に時間がかかっている印象がある。依存パッケージを増やすたびにビルド時間が伸びるので、パッケージの追加には慎重になった。

Cloudflare Workers互換の苦労。Next.jsはVercelに最適化されている。Cloudflare Workersにデプロイするには @opennextjs/cloudflare を使う必要があり、互換性の問題に何度もハマった。

next/ogImageResponse が動かない、Node.js固有のAPIが使えない、バンドルサイズの上限に引っかかる。一つ一つは解決可能だけど、積み重なると「Vercelにデプロイしていればこの苦労は全部なかったのに」と思う瞬間がある。フレームワークとデプロイ先の相性は、最初にちゃんと検討すべきだった。

依存関係のアップデートが面倒。Next.jsは開発サイクルが速くて、メジャーバージョンアップが年に1〜2回ある。App Routerはまだ成熟途上で、マイナーバージョンでも挙動が変わることがある。next をアップデートしたらビルドが通らなくなって、2時間くらい原因調査に費やしたことが一度あった。

「シンプルに作ればよかった」

一番の後悔は、最初からシンプルに作らなかったこと。

アニメーション、ダークテーマ、スクロールエフェクト、ページ遷移のトランジション。見た目にこだわった結果、コード量が増えた。Framer Motionを入れたり、CSS変数でテーマ切り替えを実装したり。楽しかったけど、冷静に考えると個人サイトに必要だったのは、読みやすいテキストと速い表示速度だけだった。

見た目の凝ったサイトを作った直後は満足感があるけど、1ヶ月後にコードを見返すと「なんでこんな複雑にしたんだろう」と思う。個人開発あるある。

フレームワーク選定の振り返り

それでもNext.jsで良かった理由

後悔はいくつかあるけど、トータルではNext.jsで良かったと思っている。

学びの量が段違い。App Router、React Server Components、Cloudflare Workers互換、OGP画像生成、Markdown処理パイプライン。この個人サイトを作る過程で触れた技術の幅は、AstroやHugoで作っていたら得られなかったもの。

AIとの相性が良い。Claude CodeでUIコンポーネントを生成させる時、Next.jsのコードはかなりの精度で出してくれる。「App Routerのlayout.tsxで共通ヘッダーを実装して」「generateMetadataでOGP設定して」みたいな指示で、ほぼそのまま使えるコードが出てくる。マイナーなフレームワークだとこうはいかない。

拡張性に余裕がある。ブログ機能の追加、OGP画像の自動生成、API Routes。やりたいことが増えた時に、Next.jsなら大抵のことは対応できる。今は使っていないけど、将来的にRSSフィードやサイトマップの自動生成を追加する時も、Next.jsのAPIを使えば簡単にできる。

個人開発のフレームワーク選びに正解はない。目的と状況に合ったものを選ぶしかない。自分の場合は「学びの最大化」が目的だったから、Next.jsは正解だった。コスパを重視するなら別の選択肢がある。それだけの話。

関連記事

SharePost

他の記事