next-export-optimize-imagesとnext-image-export-optimizerの違い|Next.js 16対応と選び方
Next.jsでoutput: 'export'を指定すると、next/imageの既定ローダーによる画像最適化が公式に非対応になります。これを埋める代表的なライブラリが next-export-optimize-images と next-image-export-optimizer で、どちらもビルド時に変換済み画像を書き出す点は同じです。ただし2026年7月26日時点で両者の立ち位置は並列ではありません。Next.js 16がTurbopackを既定バンドラにしたことで、対応状況にはっきり差がつきました。
まとめ
- Next.js 16系(安定版16.2.12)で静的エクスポートするなら next-image-export-optimizer 1.20.1。npmのpeerDependenciesに
next: ^16.0.0を含むのはこちらだけです。 - next-export-optimize-images の最新版4.7.0はpeerDependenciesが
next: 14.x || 15.x止まりで、Next.js 16対応PR #1302は2026年5月13日の投稿以来マージされていません。 - Next.js 15以下で固定されているプロジェクトなら next-export-optimize-images に分があります。Pictureコンポーネントによる複数フォーマット併配信など、機能面ではこちらが厚い構成です。
- 画像が数点しかない、SVGとGIFだけ、すでに画像CDNがある——このいずれかならライブラリは不要で、
images.unoptimizedかカスタムローダーで足ります。
以下、この判断の根拠を、静的エクスポートで画像最適化が止まる仕組みから順に説明します。
output: “export” で next/image の最適化が止まる仕組み
Next.jsの静的エクスポートは、next build時にルートごとのHTMLを生成してoutディレクトリへ書き出す動作です。設定は next.config.js の1行だけです。
// next.config.js
const nextConfig = {
output: 'export',
}
module.exports = nextConfig
公式ドキュメント「How to create a static export of your Next.js application」の Unsupported Features には、静的エクスポートで使えない機能として “Image Optimization with the default loader” が明記されています。公式のエラーページ export-image-api はその理由を「既定のローダーはImage Optimization APIに依存しており、それはエクスポートされたアプリケーションでは利用できない」「Next.jsは画像をビルド時ではなく、ユーザーのリクエストに応じてオンデマンドで最適化する」と説明しています。サーバが存在しない静的出力とは原理的にかみ合わない、ということです。Cookies、Rewrites、Redirects、Headers、ISR、Server Actionsが同じ非対応リストに並ぶのも同じ理由です。
なおnext exportコマンド自体は Next.js v14.0.0 で削除され、"output": "export"に置き換わっています(v13.3.0で非推奨化)。古い記事の手順に従ってnext exportを叩くとコマンドが見つからないので、まずここを確認してください。静的出力とサーバレンダリングの前提差についてはレンダリングとは?ブラウザ描画の仕組みとCSR/SSR/SSGの違い・選定基準を解説で整理しています。
回避策は3系統に分かれます。最適化を諦める(images.unoptimized)、外部の画像配信サービスへ委ねる(カスタムローダー)、ビルド時に変換済み画像を吐かせる(本記事の2ライブラリ)です。以降で2ライブラリを先に見て、最後にライブラリ不要のケースを扱います。
next-export-optimize-images 4.7.0 の導入手順とNext.js 16での制約
next.config.jsのラップとビルドコマンドの変更
このライブラリの特徴は、既存コードへの侵襲が小さいことです。npm i -D next-export-optimize-imagesで入れたあと、next.config.js を専用の関数でラップし、ビルドコマンドを1つ足し、画像コンポーネントのimport元を差し替えれば完了します。
// next.config.js
const withExportImages = require('next-export-optimize-images')
module.exports = withExportImages({
output: 'export',
})
{
"scripts": {
"build": "next build && next-export-optimize-images"
}
}
import Image from 'next-export-optimize-images/image'
ES Modules形式のnext.config.mjsでもimport withExportImages from 'next-export-optimize-images'として同じように書けます。next/legacy/imageを使っているコードにはnext-export-optimize-images/legacy/imageが用意されています。画質やリモート画像などの細かい設定はプロジェクトルートのexport-images.config.jsに置く方式です。バージョン4.7.0の依存はsharp ^0.34.3、実行環境はNode.js 18以上を要求します。
Turbopack既定化で静的インポート画像が最適化から外れる問題
ここが2026年時点の最大の注意点です。npmに公開されている4.7.0(2025年8月31日リリース)のpeerDependenciesはnext: 14.x || 15.xで、16が入っていません。npm 7以降はpeerDependenciesの不一致をERESOLVEエラーとして扱うため、Next.js 16のプロジェクトでは--legacy-peer-depsなどの回避指定なしにはインストールが通りません(yarnやpnpmは警告で通す場合があります)。
宣言だけの問題ではありません。同リポジトリのPR #1302「fix: add next 16 + turbopack compatibility」(2026年5月13日投稿、2026年7月26日時点でstate=open・未マージ)は、次のように問題を説明しています——Next.js 16はnext buildの既定バンドラをTurbopackにしたが、Turbopackは next.config.js のwebpack(config, …)コールバックを無視する。このライブラリは、静的インポートしたローカル画像(import img from './foo.png')を最適化マニフェストへ登録するのにそのフックを使っていた。結果として、既定設定のNext.js 16ビルドではローカル画像のインポートがマニフェストから静かに漏れ、変換画像が1枚も出力されない。
PR本文の説明に従うなら、回避策はnext build --webpackでバンドラをwebpackへ戻すことになります。Next.js 16はカスタムwebpack設定を持つアプリのためにこのフラグを残しているため、webpackに戻せば従来のフックは動く理屈です。ただしこれは実行確認済みの手順ではないので、採用するならout配下に変換画像が実際に書き出されているかをビルドごとに確認してください。Turbopack既定化を含むNext.js 16系の変更点はNext.js 16.3とは?Turbopack永続キャッシュとInstant Navigationsなど新機能を実装者目線で解説にまとめています。
next-image-export-optimizer 1.20.1 のセットアップと既知の不具合
next.config.jsのenvブロックとExportedImageへの差し替え
もう一方は、next.config.jsでloader: "custom"を宣言し、ビルド後にCLIで画像を変換する構成です。Next.jsのバンドラに手を入れないため、Turbopackが既定になっても仕組みが崩れません。バージョン1.20.1は2025年12月26日リリースで、リリースノートの先頭項目が「Upgrade to Next 16」(PR #259)です。peerDependenciesはnext: ^14.2.18 || ^15.0.3 || ^16.0.0で、16を明示的に含みます。
// next.config.js
module.exports = {
output: "export",
images: {
loader: "custom",
imageSizes: [16, 32, 48, 64, 96, 128, 256, 384],
deviceSizes: [640, 750, 828, 1080, 1200, 1920, 2048, 3840],
},
transpilePackages: ["next-image-export-optimizer"],
env: {
nextImageExportOptimizer_imageFolderPath: "public/images",
nextImageExportOptimizer_exportFolderPath: "out",
nextImageExportOptimizer_quality: "75",
nextImageExportOptimizer_storePicturesInWEBP: "true",
nextImageExportOptimizer_generateAndUseBlurImages: "true",
},
};
インストールはnpm install next-image-export-optimizer、ビルドスクリプトはnext build && next-image-export-optimizerに変更します。コンポーネントはデフォルトエクスポートなので、import名をImageにすればJSX側の記述はそのまま流用できます。
import ExportedImage from "next-image-export-optimizer";
<ExportedImage
src="images/VERY_LARGE_IMAGE.jpg"
alt="Large Image"
width={500}
height={500}
/>
上のenvブロックはREADMEの設定例の値です。READMEは「Conversion of JPEG and PNG files to the modern WEBP format by default」と記載しており、WebP変換は既定で有効です。blurプレースホルダの自動生成(generateAndUseBlurImages)もここで切り替えます。ビルド後はexportFolderPathで指定したout配下に変換画像が並ぶので、初回導入時はここを開いて出力を確認してください。
AVIF入力でsrcsetと出力ファイルがずれる既知の不具合
Next.js 16に対応しているから無条件に安全、というわけではありません。同リポジトリのopen issue #263は、元画像がAVIFでstorePicturesInWEBPを有効にした場合の不整合を報告しています。ExportedImage.js側の変換判定が["JPG", "JPEG", "PNG", "GIF"]しか見ていないためsrcsetには.AVIFのパスが出力される一方、optimizeImages.js側はAVIFもWEBPへ変換して書き出すため、本番で画像が404になるという内容です。AVIFを元素材にしているサイトは、導入前にこのissueの解決状況を確認してください。
2つのライブラリの違いと選び方
対応バージョンと機能の比較
| 項目 | next-export-optimize-images | next-image-export-optimizer |
|---|---|---|
| npm最新版 | 4.7.0(2025-08-31) | 1.20.1(2025-12-26) |
| peer next | 14.x, 15.x | 14.2.18以上, 15系, 16系 |
| peer react | 16.8以上〜19 | 18.2.0以上, 19 |
| engines node | 18以上 | 16以上 |
| 設定の置き場所 | export-images.config.js | next.config.jsのenv |
| 画像コンポーネント | Image, Picture, RemoteImage | ExportedImage |
| WebP変換 | Pictureで複数形式を併配信 | JPEG/PNGを既定で変換 |
| 外部画像 | remoteImagesに列挙 | remoteOptimizedImages.jsに列挙 |
| GitHub star | 475 | 539 |
| open issue | 13 | 12 |
数値はいずれも2026年7月26日時点のnpm registryとGitHub APIの実値です(open issue数はPRを除いた実数)。star数もissue数も拮抗しており、人気や課題の量で決められる差はありません。engines nodeの値はパッケージ側の宣言であって、Next.js 16自体がNode.js 20.9以上を要求する点に注意してください。
どちらを選ぶかの判断基準
Next.js 16系を使っている、あるいは近いうちに上げる予定があるなら next-image-export-optimizer を選ぶべきです。理由はpeerDependenciesの記載だけでなく、実装方式そのものにあります。custom loaderはnext.config.jsの設定値であってバンドラのフックではないため、webpackからTurbopackへの切り替えに影響されません。ビルド後のCLIも同様です。設計上、バンドラ交代に強い構造になっています。
ここで「リポジトリの更新が止まっているほうを避ける」という選び方をすると判断を誤ります。コミット活動だけ見れば next-export-optimize-images のほうが新しく(最終pushは2026年5月12日、next-image-export-optimizerは2025年12月26日)、放置されているわけではありません。それでも利用者から見て意味を持つのはリリース済みバージョンの対応範囲であり、そこでは「Next.js 16のリリースから9か月が経ち、対応PRも2026年5月13日の投稿以来マージされていない」という事実が効きます。commit活動ではなくリリース済みバージョンのpeerDependenciesで判断してください。
逆に、Next.js 15以下で運用が固定されているプロジェクトなら next-export-optimize-images に分があります。<Picture>によるWebPと元形式の併配信、リモート画像専用コンポーネント、ビルドモードの切り替えといった機能が揃っており、素材の形式や取得元がばらついているサイトほど効きます。この場合、将来Next.js 16へ上げるタイミングで乗り換えを再検討する、という段取りが現実的です。なお外部画像の扱いは、どちらもURLを事前にファイルへ列挙する必要がある点で共通しており、ここは選択基準になりません。
ライブラリを入れない2つの選択肢
images.unoptimized で最適化そのものを外す
next.config.jsでimages: { unoptimized: true }を指定すると、すべての画像がsrcからそのまま配信されます(Next.js 12.3.0以降)。品質・サイズ・フォーマットの変換は一切行われません。
// next.config.js
module.exports = {
output: 'export',
images: {
unoptimized: true,
},
}
公式ドキュメントはunoptimizedの使いどころとして、1KB未満の小さい画像、SVGなどのベクター画像、GIFなどのアニメーション画像を挙げています。これらは最適化しても得るものがないためです。サイト全体の画像がロゴとアイコンだけ、といったケースではライブラリを1本増やすほうが管理コスト面で不利になります。
カスタムローダーで画像CDNに任せる
ビルド時に画像を作らず、配信時の変換を外部サービスに委ねる方法もあります。next.config.jsでloader: 'custom'とloaderFileを指定し、URLを組み立てる関数を書くだけです。公式ドキュメントはCloudinaryの例を載せています。
// next.config.js
module.exports = {
output: 'export',
images: {
loader: 'custom',
loaderFile: './my-loader.ts',
},
}
// my-loader.ts
export default function cloudinaryLoader({
src,
width,
quality,
}: {
src: string
width: number
quality?: number
}) {
const params = ['f_auto', 'c_limit', `w_${width}`, `q_${quality || 'auto'}`]
return `https://res.cloudinary.com/demo/image/upload/${params.join(',')}${src}`
}
この方式ならリポジトリに変換画像を持たずに済み、ビルド時間も伸びません。すでにAmazon CloudFrontとは?仕組み・料金プランとエッジ機能・採用判断を実装者目線で解説のようなCDNを配信経路に置いているなら、画像変換機能の有無を確認したうえでローダーを1本書くほうが構成はシンプルになります。配信経路の設計はCDNとは?仕組み・キャッシュ制御からサービスの選び方まで実装目線で解説を参照してください。トレードオフは外部サービスへの依存と従量課金で、画像点数が多いサイトほどコストが読みにくくなります。
よくある質問
next export コマンドは今も使えますか
使えません。公式ドキュメントのVersion Historyによれば、next exportはv13.3.0で非推奨となり、v14.0.0で削除されて"output": "export"に置き換わりました。next.config.jsにoutput: 'export'を書けば、通常のnext buildがoutディレクトリを生成します。
output: “export” のまま next/image をそのまま使うとどうなりますか
既定ローダーでの画像最適化は静的エクスポートの非対応機能に含まれるため、そのままではビルドが通らず、公式のエラーページ export-image-api に誘導されます。images.unoptimizedを有効にするか、loader: 'custom'でローダーを指定するか、本記事の2ライブラリのいずれかを入れる必要があります。
next-export-optimize-images は Next.js 16 で使えますか
2026年7月26日時点の最新版4.7.0は公式には対応していません。peerDependenciesがnext: 14.x || 15.xのためnpmではERESOLVEになり、Turbopack対応PR #1302も未マージのままです。どうしてもNext.js 16で使うならnext build --webpackでwebpackに戻したうえで、変換画像が実際にout配下へ出ているかをビルドごとに確認してください。
next build –webpack に戻すと何を失いますか
失うのは本番ビルドの高速化です。Next.js 16の公式ブログはTurbopackで本番ビルドが2〜5倍速くなるとしており、webpackに戻すとその分が消えます。一方でnext devはTurbopackのまま使えるので、最大10倍のFast Refreshや開発時のファイルシステムキャッシュは維持できます。ビルドだけをwebpackへ退避させる、という限定的な使い方が可能です。
output: “export” では画像以外にどの機能が使えなくなりますか
公式ドキュメントのUnsupported Featuresには、dynamicParams: trueの動的ルート、generateStaticParams()のない動的ルート、Requestに依存するRoute Handlers、Cookies、Rewrites、Redirects、Headers、Proxy、ISR、既定ローダーの画像最適化、Draft Mode、Server Actions、Intercepting Routesが並びます。いずれもNode.jsサーバかリクエスト時の動的処理を必要とする機能です。