Next.jsシステム構成図 2026年版 日本と海外まとめてみた

Next.jsでシステム構成を組むのにお悩みではないでしょうか?当の私も非常に悩みました。そこで、日本と海外のさまざまな記事や公式ドキュメント、サンプルソースを調査してみることに。いろいろと面白い発見もあったので記事にまとめてみたいと思います。当然、いろいろなご意見もあると思います。その際は、コメントいただければと思います。
※今回のシステム構成は、App Routerを前提をしています。
Next.jsシステム構成図 2026版
先に結論です。今回たどり着いたフォルダ構成は、こちらです。
demo_nextjs_ts/
│
├── public/ # 静的ファイルの配信専用(Next.js規約、名前変更不可)
│ ├── images/ # 画像
│ └── js/ # 直接JSファイルを置きたい場合
│
├── app/ # URLとページの対応表(ルーティング)
│ ├── layout.tsx # 全ページ共通の外枠(ここでグローバルCSSを読み込む)
│ ├── error.tsx # アプリ全体のエラー画面
│ ├── not-found.tsx # アプリ全体の404画面
│ ├── global-error.tsx # layout自体が壊れた時の最終防衛ライン
│ ├── _components/ # アンダースコア=ルーティング対象外(Next.js規約)
│ │ ├── header.tsx # ヘッダー
│ │ └── footer.tsx # フッター
│ └── products/ # URLにアクセスされた時に対応したpage.tsxが呼び出される
│ └── [id]/
│ └── edit/
│ ├── page.tsx
│ └── not-found.tsx # 指定した商品が存在しない場合の専用404
│
├── middleware.ts # リクエストごとのフィルタ処理(他フレームワークのミドルウェア相当)
│
├── features/ # 機能別の塊。各ドメインの画面・ロジック・DB操作をまとめる
│ └── products/ # 商品機能
│ ├── dal/ # Data Access Layer。DBアクセス(MVCのモデル相当)
│ │ └── products.ts # import 'server-only'必須
│ ├── actions/ # Server Actions。保存処理(MVCのコントローラー相当)
│ │ └── update-product.ts
│ ├── hooks/ # この機能専用のカスタムフック
│ └── views/ # 画面(MVCのビュー相当)
│ └── edit/ # 編集画面の一式
│ ├── product-edit-view.tsx # 画面まるごと(本体)
│ ├── product-edit-view.module.css # この画面専用のCSS
│ └── components/ # この画面専用の小さな部品
│ └── confirm-submit-button.tsx
│
├── lib/ # 外部システムとの接続実装
│ ├── db.ts # DB接続プール
│ ├── auth.ts # Cognito等のコア認証実装
│ ├── logger.ts # ログ出力(Winston/Pino等)
│ └── definitions.ts # 型定義(Product型など)
│
├── common/ # 外部依存のない汎用処理・値
│ ├── utils.ts
│ ├── constants.ts
│ └── messages.ts # 確認ダイアログ等の文言
│
├── styles/
│ └── globals.css # サイト全体のCSS
│
├── node_modules/ # npm経由の外部ライブラリ(自動生成)
├── .env.local # DB接続情報等
├── package.json
│
└── logs/ # ログ出力先(.gitignoreに追加)
└── app.logそれぞれ解説します。
システム構成図の解説
publicフォルダ <Next.js公式> 画像やCSSなど静的なファイルを格納する、Next.jsで決められているフォルダ。assetsフォルダはNext.jsでは使用しないようです。ビルドすると/images/xxx.pngでそのままアクセスできるようになります。
appフォルダ <Next.js公式> この配下がURLと連動します。https://example.com/product/1/editのようにしたい場合、app¥product¥[1]¥editというフォルダ構成にしpage.tsxを配置します。page.tsxはNext.jsの仕様でファイル名は固定です(中身の関数名は自由)。URLが呼ばれると、このファイルが実行され、その中でactionsのファイルを呼び出します。これは、フォルダ構成自体がURLとプログラムをむすびつけるルーティングの機能を持つというNext.jsの大きな特徴でもあります。layout.tsx共通の外枠、error.tsx・not-found.tsx各種エラー画面など、共通の画面をここに配置します。
_componentsフォルダ <Next.js公式> フォルダ名の先頭にアンダースコアを付けると、Next.jsがそのフォルダをルーティングの対象から除外してくれる、という公式の規約です。これを使うことで、app/productsのような本物のURLと混同されずに、layout.tsx専用の部品を安全に置けます。中には、ヘッダーを担当するheader.tsxとフッターを担当するfooter.tsxを置いています。
middleware.ts <Next.js公式> すべてのリクエストが、各ページの処理に届く前に必ず通るファイルです。たとえば、CakePHPならbeforeFilterと同じ役割をします。Laravelならミドルウェア、SpringならHandlerInterceptor(またはServlet Filter)が同じ役割を担います。
featuresフォルダ <国内外で採用事例あり> 各URLのアクションに対する機能を実装するフォルダです。フォルダ名は公式ではありませんが、国内外を問わずfeaturesフォルダをここに配置する傾向が多いです。ちなみにfeaturesの発祥は、状態管理ライブラリ「Redux」の公式スタイルガイドが2020年頃に推奨した「feature folder」というアプローチです。Gitのブランチ名(feature/xxx)とは関係ありません。
dalフォルダ <国内外で採用事例あり> DBアクセスを専門に扱うフォルダです。同じ役割のフォルダ名として「api」を採用している記事もいくつかありました。DAL(Data Access Layer)とは、データベース等へのアクセス処理を1つの層にまとめるという、以前から存在するソフトウェア設計の用語です。
actionsフォルダ <国内外で採用事例あり> POST等のリクエスト(フォーム送信・更新・削除など)を処理する関数を置きます。
viewsフォルダ <海外で採用事例あり> MVCのVの部分。基本的にはHTMLのみを実装します。「component」を採用している事例も複数ありましたが、componentは画面内の小さなパーツ用にしたかったので、パット見でわかりやすいようにviewsにさせていただきました。「pages」を採用している事例もありました。
views/edit/componentsフォルダ <国内で採用事例あり> 画面内の小さな部品(確認ダイアログ付きボタン等)を置く場所です。Laravelでいうresources/js/product-edit.ts(フロント側のJS)に相当します。ある国内の大手企業の実例で、機能フォルダの中にcomponentsというサブフォルダを作り、画面専用の部品をまとめる構成が紹介されており、これに倣っています。中のconfirm-submit-button.tsxは、ファイル先頭に'use client'と書くことで、ブラウザ側で実行される部品(Client Component)になるという、React/Next.jsの仕組みを利用しています。
libフォルダ <Next.jsサンプル事例あり> その名とおりライブラリを配置するフォルダ。npmのライブラリは/node_modulesに配置しますが、こちらは自プロジェクトでライブラリ的に使い時に使用するものとして使います。DB接続・型定義・共通処理をここにまとめています。
commonフォルダ <独自ルール> 外部システムに依存しない、汎用的な処理・値をまとめる場所です。中には、汎用的な共通処理を置くutils.ts(国内外どちらの実例でも多数見つかった名前)、定数をまとめるconstants.ts(Next.js自身のソースコード内で複数箇所に実例あり)、画面文言をまとめるmessages.ts(多言語対応ライブラリnext-intlのmessagesという規約を1言語分だけ先取りしたもの)を置いています。
stylesフォルダ <国内外で採用事例あり> サイト全体に1つだけ必要なCSS(globals.css)を置く場所です。今回は画面専用のCSSはviews側の該当ファイルと同じ階層に置く方針(コロケーション)にしているため、stylesにはサイト全体で共通のものだけを残しています。
common/hooksフォルダ <海外で採用事例あり> 特定の機能に紐づかない、アプリ全体のどこからでも使える汎用的なフック(useDebounce等)を置く場所です。海外の解説記事でも、機能に紐づくフックはfeatures/機能名/の中に、機能をまたぐ汎用的なフックはルート直下のhooks/に、と使い分ける構成が紹介されていました。
TOPIC
Next.jsは「コンポーネントベース・アーキテクチャ」と言われており、実際に中身を見ていくと、たしかにコンポーネントごとに塊にしたいという思想を強く受けました。
今回、いろいろなシステム構成を見ていく中で、細かいレベルまで見ていくと千差万別で、みなさん情報収集、試行錯誤されながら探っているという印象をうけました。システム構成を途中で大きく変更したという事例もちらほら。
ただ、コンポーネントの中身をみると、actionsはコントローラー、viewsは画面、dalはモデルという役割分担されており、結局、ミクロまでみていくとMVCなんだなと感じてしまいました。MVCに慣れ親しみすぎたからMVC探しをしたくなっただけかも?
App RouterとPages Router どっちを選ぶ?
2023年5月、Next.jsには、大きな転換点がありました。App Routerの登場です。これまで標準はPages Routerだけでしたが、App Routerも正式に安定版(stable)として加わりました。
Pages Routerは、pagesフォルダの中にファイルを置いてルーティングが決まる仕組みでしたが、App Routerは、appフォルダを使う新しい仕組みとなりました。自分がどちらを選ぶかによって、参考にする情報もそれに合ったものを選ぶ必要があります。この記事のシステム構成はApp Router向けになります。
Pages Router と App Router の違い(2026.07時点)
| 項目 | Pages Router | App Router |
|---|---|---|
| 説明 | 2016年からの従来のページ単位・クライアント中心 | 最新のコンポーネントベース・サーバー中心 |
| 公式URL | https://nextjs.org/docs/pages | https://nextjs.org/docs/app |
| 初登場 | 2016年10月(Next.js 1.0 ) | 2022年10月(Next.js 13.0でβ登場) |
| 公式の推奨度 | 現状維持 | 現在の標準(推奨) |
| フォルダ・ファイル例 | pages/products/[id]/edit.tsx | app/products/[id]/edit/page.tsx |
| URL | /products/1/edit | /products/1/edit(同じ仕組み) |
| レンダリングの単位 | ページ単位で選択 | コンポーネント単位で選択(Server/Client Component) |
| データ取得 | getServerSideProps等の専用関数 | コンポーネント内で直接await |
| 保存処理 | API Routes(別ファイル) | Server Actions(同ファイル内で完結可) |
業務での現在の主流は?
App Routerは、2026年時点でほぼ主流になっています。あるSaaS開発会社は、2026年の新規プロジェクトでは基本的にApp Routerを選ぶとしていて、理由は開発体験の向上とTurbopackによる高速化を挙げています。ただし例外もあり、React Server Components関連のセキュリティパッチが立て続けに出た影響で、金融・医療系などではあえてPages Routerが選ばれることもあるようです。
DB接続は、TypeScript界隈ではPrismaが定番になっています。ただし最近はDrizzleやKyselyのような「SQLに近い書き味の新興ORM」も台頭してきていて、一強状態ではありません。
ファイル名やフォルダ名はケバブ?パスカル?スネーク?キャメル?
国内で確認できた複数の実務コードは、そろってPascalCase(FilterModal.tsxのような)でした。コンポーネント関連はPascalCase、関数・処理関連はcamelCaseという組み合わせで、kebab-caseは1つも出てきませんでした。
一方、海外の記事では、add-to-cart.tsx・cart-context.tsxのように、ファイル名はすべてケバブケースが主流でした。ファイルの中の関数名はパスカルケースでした。
Next.jsを開発している会社(Vercel)が公開している公式のECサイトテンプレートを直接確認すると⋯後者でした。
記事が書かれた時期や実装者にもよるかもしれませんが、国内外での慣習がちがうのもあるのかもしれません。
パスカルケースにはNext.jsに関わらず、メリット・デメリットあるので、このへんを理解したうえでどちらを採用するか決めてもよいと思います。
パスカルケースのメリットとデメリット
| メリットorデメリット | 観点 | 内容 |
|---|---|---|
| メリット | 関数名と一致 | ファイル名(ProductEditForm.tsx)と、中でエクスポートする関数名(ProductEditForm)が完全に一致するため、頭の中で変換する必要がなく、直感的に分かりやすい |
| メリット | コンポーネントだと一目で分かる | 大文字始まりのファイルは「これはReactコンポーネントだ」と、名前だけで判別できる |
| デメリット | OS間の大文字小文字バグ | Mac/Windowsは大文字小文字を区別しないが、本番サーバー(Linux)は区別する。開発中は動いても、デプロイ後だけファイルが見つからないエラーが起きることがある |
| デメリット | Next.js開発元のコードとは不一致 | Vercel公式のECサイトテンプレートは、ファイル名をkebab-caseで統一しており、PascalCaseはNext.js自身の作法とは異なる |
| デメリット | URLに使う場合は不向き | appフォルダ内、URLに変換されるフォルダ名としては、大文字はSEO・Web慣習上避けるべきとされている |
MEMO
Next.js Commerce(ECサイトテンプレート、Vercel公式)
https://github.com/vercel/commerce
Next.js公式チュートリアル(Postgresを使った請求書ダッシュボード)
https://nextjs.org/learn/dashboard-app
さいごに
今回はNext.jsのフォルダ構成について、公式ドキュメント、公式サンプル、国内外の実例まで、一通り掘り下げてみました。もちろん、これが正解というわけではありません。他にもっと良いやり方があれば、アップデートしていきたいと思います。ぜひコメントで教えてください。それでは!

