opinionated-nextjs-patterns について
Next.js 16 App Routerのコードベースを構築・レビューするチーム向けのリファレンススキルです。実行ライフサイクルに沿って50のルールを整理し、Supabaseを例に他のバックエンドにも応用できるパターンを示します。
主な機能
- 018カテゴリにわたる50のルール
- 02認可とデータ層アクセスのパターン
- 03サーバー側のデータ読み込みと変更
- 04クライアントとサーバーの境界指針
- 05Turbo monorepoアーキテクチャ
- 06フォームとUIの規約
活用シーン
- 01Next.jsの新機能の実装
- 02認可とリクエスト処理のレビュー
- 03データアクセスとパッケージ境界のリファクタリング
- 04コードベースへの開発者のオンボーディング
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ pproenca/ dot-skills --skill opinionated-nextjs-patternsインストール後、Claude Code で/opinionated-nextjs-patternsを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
AGENTS.mdmetadata.jsonassets/templates/_template.mdreferences/_sections.mdarch-app-vs-packages-boundary.mdarch-config-driven-navigation.mdarch-data-access-adapter.mdarch-feature-package-layout.mdarch-import-via-package-exports.mdarch-policy-engine-for-business-rules.mdarch-provider-gateway-pattern.mdauth-gate-admin-client.mdauth-mfa-in-middleware.mdauth-server-only-imports.mdauth-trust-rls-no-duplicate-checks.mdauth-use-require-user.mdauth-use-sql-policy-helpers.mdauth-use-standard-server-client.mdclient-pass-server-data-as-props.mdclient-realtime-cleanup-subscription.mdclient-stable-query-keys.mdclient-use-action-hook.mdclient-use-client-at-leaves.mdclient-use-supabase-with-react-query.mdmutate-enhance-route-handler.mdmutate-revalidate-path-after-write.mdmutate-thin-action-service-holds-logic.mdmutate-use-getlogger-not-console.mdmutate-use-safe-action-clients.mdmutate-webhook-verify-signature.md詳細
意見を取り入れた Next.js 16 のパターン
単一の一貫したアーキテクチャを採用する Next.js 16(App Router) コードベース向けの実装パターンリファレンスです。実行ライフサイクルにおける影響の連鎖を基準に優先順位を付けた 8 カテゴリー、50 のルールを収録しています。まず認可と(任意の)テナントモデリング、次にリクエスト境界、サーバー側のデータ取得、ミューテーション、クライアント境界、アーキテクチャ、UI の規約を扱います。
ルールは原則としてバックエンドに依存しませんが、具体例には Supabase を使用しています。各ルールでは、応用可能な考え方(例:「データレイヤーで認可する」「型付けされたリポジトリを通して読み取る」)を説明します。バックエンドが実際に関係する場合は、*Transferable:* の注記で、ほかのストア(Drizzle、Prisma)に適用するパターンを説明します。構成は、標準的なライブラリ(next-safe-action、@supabase/ssr、@tanstack/react-query、react-hook-form + zod、shadcn/ui、next-intl、pino)を基盤とする Turbo モノレポで、独自の @app/* パッケージを構築します。ベンダー提供のスターターキットを使う構成ではありません。
適用する場面
次のようなときに、これらのルールを活用してください。
- 新しいコードを書くとき — ページ、レイアウト、サーバーアクション、ルートハンドラー、
proxy.ts、機能パッケージ、クライアントコンポーネント、フック、データアクセスパッケージ、SQL/マイグレーション、フォーム。 - PR をレビューするとき — 認可の漏れ(ガードなしの特権クライアント、
'server-only'の指定漏れ)、ウォーターフォール(順次の await、クライアントによるサーバーデータの取得)、乖離(生成された型の手動編集、パッケージの深い階層からのインポート、ハードコードされた i18n 文字列)。 - リファクタリングするとき —
apps/webとpackages/*の間でのコード移動、アクションとサービスの分割、'use client'境界の引き上げ、直接クエリを型付きデータアクセスファクトリーに置き換えること、データアクセスパッケージの背後でバックエンドを切り替えること。 - 機能を設計するとき — 適切なクライアント(リクエストスコープ、特権、ブラウザー)を選ぶこと、アクションとルートハンドラーのどちらにするかを決めること、フォームとサーバーアクションの契約を計画すること、テナントのスコープを決めること(マルチテナントの場合)。
- オンボーディングするとき — 具体的で応用可能な例を通して、コードベースがそのような構成になっている理由を理解すること。
優先度別のルールカテゴリー
| 優先度 | カテゴリー | 影響 | プレフィックス |
|---|---|---|---|
| 1 | 認可とデータレイヤーアクセス | 重大 | auth- |
| 2 | マルチテナンシー (任意、SaaS のみ) | 重大 | tenant- |
| 3 | リクエスト境界(Proxy) | 高 | proxy- |
| 4 | サーバー側のデータ読み込み | 高 | server- |
| 5 | ミューテーション:アクションとルートハンドラー | 高 | mutate- |
| 6 | クライアント/サーバー境界 | 中〜高 | client- |
| 7 | アーキテクチャとサービス | 中 | arch- |
| 8 | フォームと UI の規約 | 中 | ui- |
クイックリファレンス
1. 認可とデータレイヤーアクセス(重大)
auth-use-standard-server-client— リクエストスコープで認証に紐付いたクライアントを使用し、特権クライアントをデフォルトにしないでください。auth-gate-admin-client— サービスロールクライアントを構築する前に認可してください。auth-trust-rls-no-duplicate-checks— データレイヤーで一度だけ認可し、アプリケーションコードで再確認しないでください。auth-use-sql-policy-helpers— スコープ指定の述語を再利用可能な SQL ポリシーヘルパーに集約してください。auth-use-require-user— 認証ゲートを 1 つのrequireUser()ヘルパーに集約してください。auth-server-only-imports— 特権モジュールにはimport 'server-only'を指定してください。auth-mfa-in-middleware— ページごとではなく、proxy.ts境界で MFA を適用してください。
2. マルチテナンシー(重大 — 任意、SaaS のみ)
tenant-accounts-as-tenant-root— 個人用とチーム用の両方のワークスペースが参照する、テナントルートのテーブルを 1 つ用意します。tenant-account-id-on-product-tables— すべてのプロダクトテーブルにテナントキー、インデックス、スコープポリシーを追加します。tenant-slug-in-team-urls— チーム URL では UUID ではなく、人が読めるスラッグを使用します。tenant-storage-paths-include-account-id— オブジェクトストレージのパスをテナント ID で名前空間化します。tenant-never-edit-generated-types— 生成された DB 型はビルド出力として扱い、手動で編集せずに再生成します。
3. リクエスト境界:プロキシ(高)
proxy-single-pipeline— リクエストパイプライン全体を 1 つのproxy.tsにまとめます。proxy-redirect-auth-at-boundary— 認証リダイレクトはページではなく、プロキシで行います。proxy-url-pattern-matching— 文字列比較ではなく、URLPatternでプロキシルートを照合します。proxy-set-correlation-id— リクエスト境界で相関 ID を設定します。proxy-secure-headers-flagged— 環境フラグのもとで、厳格な CSP ヘッダーを適用します。
4. サーバーサイドのデータ読み込み(高)
server-cache-workspace-loaders— React のcache()でリクエストごとのローダーをラップします。server-promise-all-parallel-loads— 独立したデータはPromise.allで並列に読み込みます。server-use-feature-api-factories—from('table')を直接使うのではなく、型付けされたデータアクセスファクトリーを介して読み込みます。server-redirect-on-missing-workspace— ワークスペースの状態が無効な場合は、ローダーからリダイレクトします。server-fetch-in-server-components— 初期データはクライアントではなく、サーバーコンポーネントで取得します。server-use-tables-generic-for-types— 手書きのインターフェースではなく、生成された行型を使用します。server-services-receive-client— サービスには、データクライアントをコンストラクター引数として渡します。
5. ミューテーション:アクションとルートハンドラー(高)
mutate-use-safe-action-clients— next-safe-action を基盤に構築した、型付けされたアクションクライアントを通してルートのミューテーションを実行します。mutate-zod-schema-separate-file— クライアントとサーバーで共有する Zod スキーマは、それぞれ独立した*.schema.tsファイルに配置します。mutate-thin-action-service-holds-logic— アクションは薄く保ち、ビジネスロジックはサービスに配置します。mutate-use-getlogger-not-console—console.logではなく、自分で用意した構造化ロガーを通してログを記録します。mutate-revalidate-path-after-write— 書き込みが成功した後にrevalidatePath()を呼び出します。mutate-enhance-route-handler— 認証とバリデーションを担う、型付けされたハンドラーでルートハンドラーをラップします。mutate-webhook-verify-signature— Webhook ルートではユーザー認証を省略し、プロバイダーの署名を検証します。
6. クライアント/サーバーの境界(中〜高)
client-use-client-at-leaves— ページのルートではなく、末端のコンポーネントに'use client'を指定します。client-pass-server-data-as-props— サーバーのデータはクライアントコンポーネントに props として渡し、再取得しません。client-use-supabase-with-react-query— クライアント側でデータを読み取る際は、メモ化されたブラウザークライアントと TanStack Query を組み合わせます。client-realtime-cleanup-subscription— サブスクリプションやイベントソースは、useEffectの戻り値で必ず解除します。client-use-action-hook—next-safe-action/hooksのuseActionでサーバーアクションを呼び出します。client-stable-query-keys— 安定した階層構造のクエリキーを使用します。
7. アーキテクチャとサービス(中)
arch-app-vs-packages-boundary— 再利用可能な機能はpackages/に、製品固有のコードはapps/webに配置します。arch-data-access-adapter— 安定したインターフェースを持つ単一のデータアクセスパッケージに、バックエンドを集約します。arch-feature-package-layout— 機能パッケージはcomponents / hooks / schema / serverの構成にします。arch-import-via-package-exports— パッケージのexportsマップ経由でインポートし、内部パスを直接指定しません。arch-provider-gateway-pattern— ベンダーの SDK をゲートウェイインターフェースの背後に隠します。arch-policy-engine-for-business-rules— インラインの条件分岐ではなく、自分たちが管理するポリシーレイヤーでビジネスルールをモデル化します。arch-config-driven-navigation— ルートとナビゲーションはコンポーネントにハードコードせず、config/で定義します。
8. フォームと UI の規約(中)
ui-rhf-zod-no-generics— フォームの型推論はzodResolverに任せ、useFormにジェネリクスを追加しません。ui-form-message-per-field— 各フィールドにFormMessageを含めます。ui-kit-ui-package-imports— UI は@app/uiのデザインシステムインターフェースからインポートし、内部パスは使用しません。ui-semantic-tailwind-tokens— ハードコードされた色ではなく、セマンティックな Tailwind トークンを使用します。ui-base-ui-render-not-aschild— Radix のasChildではなく、Base UI のrenderプロパティを使用します。ui-trans-for-display-text— 表示テキストは<Trans>またはuseTranslationsを通じてレンダリングします。
使用方法
詳しい説明やコード例については、各リファレンスファイルを参照してください。
- セクションの定義 — カテゴリー構成、影響度、ライフサイクルに関する根拠。
- ルールのテンプレート — 新しいルールを追加するためのテンプレート。
- AGENTS.md — すばやく移動するための自動生成 TOC。
リファレンスファイル
| ファイル | 説明 |
|---|---|
| references/_sections.md | カテゴリーの定義とライフサイクルへの影響度に基づく順序 |
| assets/templates/_template.md | 新しいルールを追加するためのテンプレート |
| metadata.json | バージョン、組織、リファレンス |
関連スキル
base-ui-migrator— Radix のasChildパターンを Base UI のrenderプロパティに一括移行します。tailwind-refactor— ハードコードされた色をセマンティックトークンにリファクタリングします。react-optimise— React コンポーネントのパフォーマンスを最適化します。nextjs-bundle-optimizer— Next.js アプリのバンドルを分析し、サイズを削減します。