Next.js の保守: 実践的なガイド 2026 年版

Next.js 9 からのアプリケーション保守を行ってきました。本番環境で実行され、数百万のリクエストを処理しているものもあります。一方で、誰かが(時には私が)6 ヶ月間のメンテナンスをスキップしてしまい、突然 47 の大規模バージョンアップ、3 つの非推奨 API、セキュリティチームを不安にさせた CVE に直面することになったアプリもあります。

Next.js は高速に進化しています。2024 年と 2025 年を通じてフレームワークはおよそ 6 ヶ月ごとに大規模リリースを行い、2026 年もそのペースを継続しています。Next.js プロジェクトを積極的にメンテナンスしていなければ、予想以上の速さで複利して増加する技術的負債を溜め込むことになります。このガイドは、週単位の依存関係チェックから年単位の大規模バージョンマイグレーションまで、Next.js アプリケーションを健全に保つために学んだすべてのことをカバーしています。すでにヘルプが必要なことがわかっている場合は、RFP を提出してください。確認させていただきます。

目次

Next.js メンテナンスが重要な理由

数字を見てみましょう。Snyk の 2025 State of Open Source Security レポートによると、平均的な JavaScript プロジェクトは 49 の直接依存関係と 500 以上の推移的依存関係を持っています。それぞれが潜在的な攻撃面です。脆弱性が公開されてからエクスプロイトが野生に現れるまでの中央値の時間は 2025 年に 7 日に短縮されました。7 日です。

Next.js は、バニラ React アプリにはない保守上の考慮事項を導入します:

  • サーバーサイドレンダリング攻撃面 -- Next.js アプリはサーバーで動作するコード、ブラウザでだけではありません。サーバー側の脆弱な依存関係はブラウザにサンドボックス化されたものよりもはるかに危険です。
  • API ルートと Server Actions -- これらは完全なバックエンドエンドポイントです。Express や Fastify API と同じセキュリティ厳密性が必要です。
  • ビルドパイプライン依存関係 -- SWC、webpack/Turbopack、PostCSS プロセッサ、画像最適化はすべて独自の依存関係ツリーを持っています。
  • ミドルウェア実行 -- 多くの導入ではエッジで実行され、独自の互換性とセキュリティに関する考慮事項があります。

セキュリティ以外に、SEO の角度もあります。Google の Core Web Vitals はランキング要因であり、古いコードからの Next.js パフォーマンス回帰は検索の可視性に直接影響します。Social Animal のクライアントは、Next.js 13 から 15 へのアップグレードと蓄積されたパフォーマンスの問題の修正だけで、失われた有機トラフィックの 15~20% を回復させました。

実際に機能するメンテナンススケジュールの構築

数十の Next.js プロジェクトを保守した後で得た重要な洞察: メンテナンスは退屈で定期的なときほど簡単です。それが「プロジェクト」になった瞬間、それはすでに期限切れです。

以下は私が使用するスケジュールです:

頻度 タスク 時間の見積もり
毎週 Dependabot/Renovate PR を確認し、パッチアップデートをマージ 30-60 分
隔週 npm audit を実行し、結果に対処 30 分
毎月 マイナーバージョンを更新し、変更ログの破壊的な変更を確認 2-4 時間
四半期ごと 未使用の依存関係を監査し、バンドルサイズを確認し、Node.js を更新 4-8 時間
リリースごと Next.js 大規模バージョンマイグレーション 8-40 時間
毎年 完全なセキュリティ監査、依存関係の見直し、インフラストラクチャのレビュー 16-40 時間

週単位のリズム

毎週月曜日の朝、Renovate や Dependabot などのツールが開いた自動 PR を確認します。パッチアップデート (1.2.3 → 1.2.4) は CI が成功した後にマージされます。これは最大 30 分かかり、「200 個の古いパッケージ」の状況を防ぎます。

# 毎週実行する簡単なヘルスチェック
npx npm-check-updates --target patch
npm audit --audit-level=moderate
npx next info

月単位の詳細確認

月に 1 回、マイナーバージョンアップの確認をしています。これらには新機能を含めることができますが、既存の API を破壊してはいけません。強調して言えば「破壊してはいけません」。常に変更ログを読んでください。

# マイナーアップデートをチェック
npx npm-check-updates --target minor

# 変更内容をプレビュー
npx npm-check-updates --target minor --format group

関連アップデートをグループ化します。@next/fontnext から別に更新することは問題を求めています。それらは一緒に移動すべきです。

依存関係のアップグレード: ステップバイステップの手順

これはほとんどのチームが間違えるところです。彼らは npm update を実行し、祈り、プッシュします。私が実際に何をするかは以下の通りです:

ステップ 1: 何を持っているかを理解する

何かをアップグレードする前に、依存関係の状況を知ってください。

# すべての古いパッケージの詳細をリスト
npm outdated

# 特定のパッケージの依存関係ツリーを生成
npm ls react-dom

# ロックファイルの重複をチェック
npx depcheck

ステップ 2: リスク別にアップデートを分類する

すべてのアップデートが同じではありません。私はそれらをバケットに分けます:

リスクレベル アプローチ
パッチアップデート、開発のみの依存関係、型定義アップデート バッチでマージ
ランタイム依存関係のマイナーバージョンバンプ、Next.js パッチアップデート 個別に更新し、完全なテストスイートを実行
メジャーバージョンバンプ、Next.js マイナー/メジャーアップデート、React アップデート 専用ブランチ、徹底的なテスト、段階的なロールアウト
緊急 ランタイム依存関係のセキュリティパッチ 同じ日のアップデート、緊急プロセス

ステップ 3: 隔離されたブランチを作成する

パッチアップデート以上のすべてのもの:

git checkout -b deps/update-2026-05

# 特定のパッケージをアップデート
npm install next@latest react@latest react-dom@latest

# すぐにビルドを実行 -- 待たないで
npm run build

# テストスイートを実行
npm test

# TypeScript を使用している場合は型エラーをチェック
npx tsc --noEmit

ステップ 4: ランタイムの動作を確認する

昨年、クライアントサイトでこれに取り組みました: ビルドは成功し、テストは緑色で、紙の上ではすべてが良好に見えました。その後、Server Components が本番環境で水分補給の不一致をスローし始めました。これは依存関係がマイナーバンプで出力形式を変更したためです。ビルドが成功してテストが緑色であっても、すべてが機能することは意味しません。

私は常に:

  1. 開発サーバーを実行し、重大なパスをクリックスルーで手動で確認
  2. Server Components が正しくレンダリングされるかを確認 (水分補給の不一致は隠れるのが好き)
  3. API ルートが期待される応答を返すことを確認
  4. ミドルウェアの動作を確認、特に認証フロー
  5. 画像最適化がまだ機能しているかを確認 (next/image コンポーネントはアップデート間で破壊されたことがあります)

この種の作業のスコープの途中にあり、その背後にあるチームが必要な場合は、RFP を送信してください。正しいアプローチを一緒に考えましょう。

ステップ 5: デプロイ後にモニタリングする

マージして忘れないでください。依存関係アップデートのデプロイ後 48 時間、エラー追跡 (Sentry、LogRocket) とパフォーマンスモニタリングを監視してください。

Next.js 2026 年のセキュリティ強化

Next.js のセキュリティは大幅に進化しています。Next.js 14 で導入され、15 と 16 を通じて成熟した Server Actions モデルは、攻撃面を完全に変えました。今どこに焦点を当てるべきかは以下の通りです。

Server Action セキュリティ

Server Actions は本質的に公開 API エンドポイントです。そのように扱ってください。

// 悪い例 -- 検証なし、認証チェックなし
'use server'
export async function deleteUser(userId: string) {
  await db.user.delete({ where: { id: userId } })
}

// 良い例 -- 検証済み、認証済み、認可済み
'use server'
import { z } from 'zod'
import { auth } from '@/lib/auth'

const deleteUserSchema = z.object({
  userId: z.string().uuid(),
})

export async function deleteUser(rawData: unknown) {
  const session = await auth()
  if (!session?.user) throw new Error('Unauthorized')
  
  const { userId } = deleteUserSchema.parse(rawData)
  
  // ユーザーがこの特定のユーザーを削除する権限があるかをチェック
  if (session.user.role !== 'admin') throw new Error('Forbidden')
  
  await db.user.delete({ where: { id: userId } })
  revalidatePath('/admin/users')
}

セキュリティヘッダー

next.config.js (または 2026 年の next.config.ts -- TypeScript 設定は Next.js 15 以降安定) はセキュリティヘッダーを設定すべきです:

// next.config.ts
import type { NextConfig } from 'next'

const securityHeaders = [
  { key: 'X-DNS-Prefetch-Control', value: 'on' },
  { key: 'Strict-Transport-Security', value: 'max-age=63072000; includeSubDomains; preload' },
  { key: 'X-Frame-Options', value: 'SAMEORIGIN' },
  { key: 'X-Content-Type-Options', value: 'nosniff' },
  { key: 'Referrer-Policy', value: 'strict-origin-when-cross-origin' },
  { key: 'Permissions-Policy', value: 'camera=(), microphone=(), geolocation=()' },
]

const config: NextConfig = {
  async headers() {
    return [
      {
        source: '/(.*)',
        headers: securityHeaders,
      },
    ]
  },
}

export default config

Content Security Policy

CSP は Next.js では難しいです。水分補給のためのインラインスクリプトのため。nonce ベースのアプローチが最適に機能します:

// middleware.ts
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'

export function middleware(request: NextRequest) {
  const nonce = Buffer.from(crypto.randomUUID()).toString('base64')
  const cspHeader = `
    default-src 'self';
    script-src 'self' 'nonce-${nonce}' 'strict-dynamic';
    style-src 'self' 'nonce-${nonce}';
    img-src 'self' blob: data:;
    font-src 'self';
    object-src 'none';
    base-uri 'self';
    form-action 'self';
    frame-ancestors 'none';
    upgrade-insecure-requests;
  `
  
  const response = NextResponse.next()
  response.headers.set('Content-Security-Policy', cspHeader.replace(/\s{2,}/g, ' ').trim())
  response.headers.set('x-nonce', nonce)
  return response
}

npm Audit ワークフロー

単に npm audit を実行しないでください。結果を体系的に処理してください:

# トラッキング用に JSON レポートを生成
npm audit --json > audit-report.json

# 自動修正できるものを修正
npm audit fix

# メジャーバンプが必要なしぶとい問題のため
npm audit fix --force  # これは慎重に

# 既知の脆弱性について特定のパッケージをチェック
npx is-my-node-vulnerable

修正がまだ利用できないパッケージの場合は、package.jsonnpm audit オーバーライドを使用します:

{
  "overrides": {
    "vulnerable-transitive-dep": ">=2.1.1"
  }
}

自動化ツールと CI/CD 統合

自動化は、よくメンテナンスするチームとそうでないチームを分けるものです。2026 年の私のスタックは以下の通りです:

Renovate Bot 設定

Dependabot より Renovate を Next.js プロジェクトに使用しています。設定がより柔軟で、モノレポを より上手く処理します。

{
  "$schema": "https://docs.renovatebot.com/renovate-schema.json",
  "extends": ["config:recommended"],
  "schedule": ["every weekend"],
  "packageRules": [
    {
      "matchPackageNames": ["next", "react", "react-dom", "@types/react", "@types/react-dom"],
      "groupName": "React + Next.js core",
      "automerge": false
    },
    {
      "matchUpdateTypes": ["patch"],
      "matchPackagePatterns": ["eslint", "prettier", "@types/"],
      "automerge": true,
      "automergeType": "branch"
    },
    {
      "matchPackagePatterns": ["*"],
      "matchUpdateTypes": ["major"],
      "enabled": true,
      "automerge": false,
      "labels": ["major-update", "needs-review"]
    }
  ],
  "vulnerabilityAlerts": {
    "enabled": true,
    "labels": ["security"]
  }
}

依存関係の更新のための CI パイプライン

CI は依存関係が変更されたときにテストを実行する以上のことを行うべきです:

# .github/workflows/dependency-check.yml
name: Dependency Update Validation
on:
  pull_request:
    paths:
      - 'package.json'
      - 'package-lock.json'

jobs:
  validate:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: '22'
          cache: 'npm'
      - run: npm ci
      - run: npm run build
      - run: npm test
      - run: npm audit --audit-level=high
      - name: Bundle size check
        run: npx size-limit
      - name: Lighthouse CI
        uses: treosh/lighthouse-ci-action@v12
        with:
          configPath: './lighthouserc.json'

サプライチェーンセキュリティのための Socket.dev

すべてのプロジェクトに Socket.dev を追加しました。npm audit が見逃すものをキャッチします。新しいバージョンで突然ネットワーク呼び出しやファイルシステムアクセスを追加するパッケージなど。昨年私が取り組んだプロジェクトでは、2 つの疑わしいアップデートをキャッチしました。

Next.js の大規模バージョンマイグレーション処理

大規模バージョンマイグレーションは独自のセクションに値します。それは最も時間がかかり、危険なメンテナンスタスクだからです。

マイグレーション再生ブック

  1. 公式マイグレーションガイドを完全に読んでください コードを書く前に。Vercel はすべての大規模リリースの詳細な codemods とガイドを公開しています。

  2. 最初に codemods を実行してください。 Next.js はほとんどの名前変更と API 変更を処理する自動 codemods を提供しています:

npx @next/codemod@latest upgrade
  1. コンパイラエラーを修正してください。 codemod の後、TypeScript コンパイルを実行し、破壊されたものを修正します。

  2. Server Components と Client Components の境界をテストしてください。 大規模バージョンでは、コンポーネントタイプに関するデフォルト動作が変わることが多いです。

  3. データフェッチパターンを確認してください。 getServerSideProps から Server Components への移行は、Next.js の最大の破壊的な変更でした (Next.js 13)。その後のバージョンでは、この領域の改善が続いています。

  4. デプロイメント設定を更新してください。 Vercel はこれを自動的に処理しますが、別のプラットフォームでセルフホストしているか使用している場合は、Dockerfile、ビルドスクリプト、またはサーバーレス設定を更新する必要があります。

2026 年の特定のバージョン注

マイグレーション キーの変更 推定時間 (中規模アプリ)
Next.js 14 → 15 非同期リクエスト API、React 19、Turbopack 安定 16-24 時間
Next.js 15 → 16 キャッシングのデフォルトの更新、React Compiler 統合 8-16 時間

次の 13 以前を実行している場合は、段階的なマイグレーションか新規ビルドが実際に意味があるかを真剣に検討してください。Social Animal でこの決定をするチームを支援しています。時には正直な答えは「始めからやり直す」です。

メンテナンスとしてのパフォーマンスモニタリング

メンテナンスは単に依存関係を最新に保つことではありません。ユーザー (と Google) が気付く前にパフォーマンスの回帰をキャッチすることについてです。

何をモニタリングするか

  • Core Web Vitals: LCP、CLS、INP (Interaction to Next Paint は 2024 年に FID を置き換えました)。Vercel Analytics、Google Search Console、または CrUX データを使用します。
  • ビルド時間: 3 ヶ月でビルド時間が 2 倍になった場合、何か間違っています。CI でトラッキングしてください。
  • バンドルサイズ: @next/bundle-analyzersize-limit でバジェットを設定します。
  • サーバーの応答時間: 特に Server Components と API ルート用。
  • エラーレート: アップデート後のスパイクは回帰を示します。
# プロジェクトにバンドル分析を追加
npm install @next/bundle-analyzer
// next.config.ts
import withBundleAnalyzer from '@next/bundle-analyzer'

const config = withBundleAnalyzer({
  enabled: process.env.ANALYZE === 'true',
})({
  // your config
})

export default config

毎月 ANALYZE=true npm run build を実行し、結果を比較してください。増加し続けるバンドルサイズは、マイナーアップデートで大量の重量を追加した依存関係を指しています。

リビルドかアップグレードか

これは誰も聞きたくない難しい質問です。以下は私の決定フレームワークです:

この場でアップグレードする場合:

  • 1~2 の大規模バージョンが遅れている
  • コードベースは最新のパターン (App Router、Server Components) に従っている
  • テストが重大なパスをカバーしている
  • チームは既存のコードベースを理解している

リビルドを検討する場合:

  • 3 以上の大規模バージョンが遅れている
  • アプリはまだ Pages Router にあり、App Router 機能が必要
  • 依存関係以上の大きな技術的負債が蓄積している
  • 元の建築は現在の要件に適さない

異なるフレームワークへの移行を検討する場合:

  • サイトはほとんど静的で、Next.js はオーバースペック (Astro を確認してください)
  • Next.js パターンに対抗している。Next.js パターンで作業している
  • チームは異なるスタックの専門知識を持っている

ヘッドレス CMS でコンテンツが多いサイトを実行している場合、時々 目的に合わせた建築に切り替わる は、元の範囲を超えて進化した Next.js アプリを保守するより多くの時間を節約します。オプションについて正直に 話し合う のは常に喜びです。

FAQ

Next.js 依存関係をどのくらいの頻度でアップデートすべきですか?

パッチアップデートは毎週行うべきです。これらはほぼ常に安全で、多くの場合セキュリティ修正を含みます。マイナーアップデートは月ごと、変更ログを確認した後。大規模バージョンは安定リリースの 2~3 ヶ月以内に、エコシステムが追いつく時間を持つまで。6 ヶ月以上大規模バージョンを待つことで大幅なアップグレード痛を引き起こします。

npm audit fix --force を使用しても安全ですか? 慎重に確認せずに数値を実行していません。--force フラグは依存関係の大規模バージョンバンプを許可し、破壊的な変更を導入できます。私はそれを開始点としてのみ使用します。ブランチで実行し、徹底的にビルドしてテストし、マージ前に package-lock.json のすべての変更を確認してください。本番アプリケーションの場合、特定の脆弱なパッケージを手動で更新する方が、ほぼ常に安全です。

Next.js 依存関係の更新を自動化するための最適なツールは何ですか?

2026 年の私のトップピックは Renovate Bot です。グループ化されたアップデート (nextreactreact-dom の同期を維持) を処理し、低リスク更新の自動マージをサポートし、優れたモノレポサポートがあります。Dependabot はより単純なセットアップに問題なく機能します。Socket.dev は、使用する更新ツールに関係なく、サプライチェーンセキュリティのための追加レイヤーとして不可欠です。

推移的な依存関係でセキュリティ脆弱性を処理するにはどうすればよいですか?

最初に、脆弱なパッケージをプルダウンする直接依存関係を更新することで修正されるかを確認してください。そうでない場合は、package.json (npm) または resolutions (yarn) の overrides を使用して特定のバージョンを強制します。最後の手段として、脆弱性が更新できないパッケージにある場合は、親の依存関係全体を置き換えることができるか、patch-package を使用してパッチを追加することを検討してください。

リリースされたときにすぐに最新の Next.js バージョンにアップグレードすべきですか?

本番アプリの場合はしません。大規模リリースの後 2~4 週間待って、初期の一連のバグ修正を待ってください。Next.js GitHub の問題とコミュニティを X/Twitter でフォローして、初期の問題レポートを探してください。マイナーおよびパッチリリースの場合は、より攻撃的にできます。これらは通常、リリース後数日で安全です。

ソロ開発者の場合、Next.js アプリを保守するにはどうすればよいですか?

自動化があなたの最良の友達です。パッチアップデートの自動マージで Renovate Bot を設定し、すべての依存関係 PR でビルドとテストを実行するように CI を設定し、毎月手動レビュー用に固定 2 時間ブロックを確保してください。私が概説したスケジュールはソロ開発者向けにスケールダウンします。週単位のチェックは自動 PR の 15 分のちらっと見になり、月単位の詳細確認は 2 時間のままです。

2026 年で Next.js を使用すべき Node.js バージョンは何ですか?

Next.js 16 は Node.js 18.18 以上を必要としますが、Node.js 22 LTS (2024 年 10 月に LTS に入り、2027 年 4 月までサポートされます) を実行することをお勧めします。Node.js 20 LTS も問題ありません。特定の互換性要件がない限り、Node.js 18 を避けてください。2025 年 4 月に終了に達し、もう本番環境にあるべきではありません。

インハウス開発者がいる場合、専門的なメンテナンスに費用をかける価値はありますか?

チームの帯域幅と専門知識によって異なります。インハウス開発者は、機能作業が常により緊急に感じられるため、多くの場合メンテナンスを優先順位を下げます。Next.js アプリが事業上重要で、メンテナンスが一貫して滑る場合、専門チームとの 専用メンテナンス契約 はそれが実際に起こることを保証します。我々は多くのチームを見た、ここで延期されたメンテナンスの費用は、定期的な専門的な手入れが何をするかをはるかに超えていました。延期を止める準備ができていますか? 48 時間以内に提案を取得 し、アプリが何を必要とするかを一緒に考えましょう。