
前回の記事で、このブログサイトの機能実装について書きました。 今回は、なぜその技術を選んだかという視点から、技術スタックの選定理由についてまとめます。
個人開発での技術選定は、実用性と学びのバランスを取る必要があります。 このプロジェクトでは、実際に動くものを作りながら、新しい技術も学びたいという想いがありました。 そのため、単に「流行っているから」ではなく、「なぜその技術がこのプロジェクトに適しているか」を考えて選定しました。
この記事では、主要な技術選定について、選んだ理由と他の選択肢との比較をまとめます。 同じように技術選定で迷っている人の参考になればと思います。
フロントエンドフレームワークとして、Next.js 15を選びました。 理由はいくつかありますが、主なポイントは以下の通りです。
Next.js 15 では、App Router(appディレクトリ)がデフォルトになっています。
これまでの Pages Router(pagesディレクトリ)と比べて、以下の点が魅力的でした。
layout.tsxで共通レイアウトを管理できるloading.tsxでローディング UI を簡単に実装できるerror.tsxでエラー境界を設定できる特に、ブログサイトのようなコンテンツ中心のサイトでは、ファイルベースルーティングが相性が良いと感じました。
記事一覧(/articles)や記事詳細(/articles/[id])を、ディレクトリ構造で自然に表現できます。
Next.js 15 では、React Server Components(RSC)がデフォルトで使えます。 これにより、サーバー側でデータを取得してレンダリングできるため、クライアント側の JavaScript バンドルサイズを削減できます。
ブログサイトの場合、記事データはサーバー側で取得するのが自然です。 RSC を使うことで、初期表示が速くなり、SEO も改善されます。
Next.js では、ページごとにレンダリング方式を選べます。
このブログサイトでは、記事は動的に追加・更新されるため、SSR を使っています。 将来的に記事数が増えたら、ISR を検討することも考えています。
Next.js を選ぶ前に、他のフレームワークも検討しました。
Remix もサーバーサイドレンダリングに優れたフレームワークですが、以下の理由で Next.js を選びました。
Astro は、コンテンツ中心のサイトに適したフレームワークですが、以下の理由で Next.js を選びました:
SvelteKit も軽量で魅力的ですが、以下の理由で Next.js を選びました。
TypeScript を採用した理由は、型安全性の重要性を感じていたからです。
個人開発でも、型安全性は開発速度を上げてくれます。 特に、API のレスポンス型や、コンポーネントの props 型を定義することで、バグを減らせます。
スタイリングには、Tailwind CSSを選びました。理由は以下の通りです。
Tailwind CSS は、ユーティリティクラスを使ってスタイリングする方式です。
例えば、text-centerで中央揃え、bg-blue-500で背景色を指定します。
この方式の利点は、CSS ファイルを書かずにスタイリングできることです。 HTML とスタイルが同じ場所にあるため、コードの見通しが良くなります。
また、デザインシステムと相性が良く、一貫したスタイリングがしやすいです。
ブログサイトでは、統一感のあるデザインが重要です。Tailwind CSS では、テーマ設定でカラーパレットやスペーシングを一括管理できるため、デザインシステムを構築しやすくなります。
このブログサイトでも、カスタムカラー(ブランドカラー)を定義して、一貫したデザインを実現しています。
Tailwind CSS は、使用されているクラスのみを CSS ファイルに含めるため、未使用の CSS が生成されません。そのため、バンドルサイズが小さくなり、パフォーマンスが向上します。
Tailwind CSS を選ぶ前に、他のスタイリング方法も検討しました。
CSS Modules は、スコープが限られた CSS を書く方式ですが、以下の理由で Tailwind CSS を選びました。
styled-components は、CSS-in-JS のライブラリですが、以下の理由で Tailwind CSS を選びました。
Emotion も CSS-in-JS のライブラリですが、上記と同じ理由で Tailwind CSS を選びました。
バックエンド・インフラには、Cloudflare Workersを選びました。理由は以下の通りです。
Cloudflare Workers は、エッジコンピューティングプラットフォームです。 エッジとは、ユーザーに近い場所でコードを実行する仕組みです。
これにより、以下の利点があります。
ブログサイトの場合、世界中のユーザーがアクセスする可能性があるため、エッジコンピューティングが相性が良いと考えました。
サーバーレスアーキテクチャを採用することで、以下の利点があります。
個人開発では、運用コストを抑えたいため、サーバーレスが適していました。
Cloudflare Workers には無料プランがあり、個人ブログであれば十分なリクエスト数が含まれています(詳細は公式サイトで確認してください)。
個人ブログであれば、無料プランで十分な場合が多いです。 また、他の Cloudflare サービス(D1、R2)と統合しやすい点も魅力的でした。 有料プランも比較的低価格で、必要に応じてアップグレードできる点も良かったです。
データベースには、Cloudflare D1を選びました。D1 は、SQLite ベースのデータベースです。
個人ブログのような小規模なサイトには、SQLite で十分です。 また、開発環境でもローカルで SQLite を使えるため、開発が楽です。
D1 は、Cloudflare Workers から直接アクセスできるため、エッジからデータベースにアクセスできます。これにより、レイテンシが削減されます。
ただし、D1 は現時点では単一リージョンでの運用です。将来的には、エッジでの読み取りレプリカも検討されているようです。
D1 には無料プランがあり、個人ブログであれば十分なリソースが含まれています(具体的な制限は公式サイトで確認してください)。
個人ブログであれば、無料プランで十分です。記事データやタグ情報程度であれば、無料プランの範囲内で運用できるでしょう。
D1 を選ぶ前に、他のデータベースも検討しました。
PostgreSQL や MySQL は、より高機能なデータベースですが、以下の理由で D1 を選びました。
画像ストレージには、Cloudflare R2を選びました。R2 は、S3 互換のオブジェクトストレージです。
R2 は、AWS S3 と互換の API を持っているため、S3 用のライブラリがそのまま使えます。
例えば、@aws-sdk/client-s3や@aws-sdk/s3-request-presignerが使えます。
既存の知識やライブラリを活かせる点が魅力的でした。
R2 の最大の利点は、エグレス費用がかからないことです。S3 では、データの転送量に応じてエグレス費用がかかりますが、R2 では無料です。
ブログサイトの場合、画像を頻繁に読み込むため、エグレス費用がかさむ可能性があります。R2 を使うことで、コストを抑えられます。
R2 は、画像などの静的ファイルを保存するのに適しています。Presigned URL を使えば、セキュアにアップロードできます。
認証には、Cloudflare Access + JWTを選びました。理由は以下の通りです。
Cloudflare Access を使うと、管理画面へのアクセスを簡単に制限できます。 JWT トークンを使って認証し、Cloudflare Workers 側で検証します。
個人ブログの場合、管理者は自分だけなので、複雑な認証システムは不要でした。シンプルな認証フローで十分です。
Cloudflare Access は、Zero Trust アーキテクチャを採用しています。 Zero Trust とは、「信頼しない、常に検証する」という考え方です。
すべてのリクエストを検証することで、セキュリティが向上します。
Cloudflare Access を選ぶ前に、他の認証方法も検討しました。
NextAuth.js は、Next.js 向けの認証ライブラリですが、以下の理由で Cloudflare Access を選びました。
Auth0 も認証サービスですが、上記と同じ理由で Cloudflare Access を選びました。
リンター・フォーマッターには、Biomeを選びました。理由は以下の通りです。
Biome は、Rust で実装されているため、非常に高速です。ESLint + Prettier の代替として使えます。
開発体験が向上します。
Biome は、リンターとフォーマッターが統合されています。そのため、設定ファイルが一つで済みます。
ESLint + Prettier の場合、設定ファイルが複数必要になりますが、Biome では一つで済みます。
テストランナーには、Vitestを選びました。理由は以下の通りです。
Vitest は、Vite ベースで実装されているため、非常に高速です。 Jest と比べて、テストの実行速度が速いです。
開発体験が向上します。
Vitest は、Jest と互換性があります。Jest の API がそのまま使えるため、移行が楽です。
既存のテストコードをそのまま使えます。
E2E テストには、Playwrightを選びました。理由は以下の通りです。
Playwright は、Chromium、Firefox、WebKitの複数ブラウザに対応しています。 そのため、クロスブラウザテストが簡単です。
Cypress も E2E テストツールですが、以下の理由で Playwright を選びました。
デプロイには、OpenNext + Cloudflare Workersを選びました。理由は以下の通りです。
OpenNext は、Next.js アプリケーションを Cloudflare Workers にデプロイするためのツールです。 Next.js の機能(SSR、API Routes、画像最適化など)を維持しながら、Cloudflare Workers で動かせます。
OpenNext は、Edge Runtime に最適化されています。Cloudflare Workers の制約に合わせて、Next.js アプリケーションを変換します。
Vercel は、Next.js の公式デプロイプラットフォームですが、以下の理由で Cloudflare Workers を選びました。
Cloudflare Workers には無料プランがあり、個人ブログであれば十分なリソースが含まれています(詳細は公式サイトで確認してください)。
個人ブログであれば、無料プランで十分です。実際に運用してみて、トラフィックが増えた場合に有料プランへのアップグレードを検討するという方針で問題ないかなと思います。
技術選定を振り返ると、以下の点が良かったと思います。
一方で、以下の点は改善の余地があったと思います。
現時点では、選んだ技術スタックで十分に満足しています。
この記事では、Mosslog の技術選定について、なぜその技術を選んだかという視点からまとめました。 個人開発での技術選定は、実用性と学びのバランスを取ることが重要です。
次回は、実際の開発で遭遇した課題と解決方法について詳しく書く予定です。 技術選定はできても、実際に使ってみると様々な課題に直面します。
同じように技術選定で迷っている人の参考になれば嬉しいです。