Next.js の開発は、まず npm run dev で開発サーバーを立ち上げるところから始まります。この裏で動いているのが next dev というコマンドです。ふだんは何も考えずに実行しているコマンドですが、ポートを変えたい、スマホの実機で表示を確かめたい、Turbopack を試したい、といった場面ではオプションを知っておく必要があります。この記事では App Router・Next.js 15 系を前提に、next dev の基本と主なオプション、そして起動できないときの対処までを解説します。
目次
next dev は開発専用のサーバーを起動するコマンド
next dev は、開発中のアプリを手元のブラウザで確認するためのサーバーを起動します。既定では http://localhost:3000 で待ち受け、ブラウザからアクセスするとその場でページがコンパイルされて表示されます。
いちばんの特徴は、ソースコードを保存すると変更が自動でブラウザに反映されることです。Next.js ではこの仕組みを Fast Refresh と呼びます。手動でリロードする必要がないので、スタイルを少し調整して見た目を確かめる、といった往復が非常に速くなります。
逆に言うと、next dev が用意するのはあくまで開発用の環境です。表示中のページだけをその都度コンパイルする作りになっているため、本番のようにアプリ全体を最適化した状態にはなっていません。この違いについては記事の後半で改めて触れます。
next dev の起動方法
create-next-app で作ったプロジェクトなら、package.json の scripts に dev が最初から登録されています。ふだんは next コマンドを直接叩かず、npm スクリプト経由で実行するのが一般的です。
{
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start"
}
}
あとはプロジェクトのディレクトリで次のコマンドを実行するだけです。
# npm の場合
npm run dev
# yarn / pnpm の場合
yarn dev
pnpm dev
# next コマンドを直接実行する場合
npx next dev
起動に成功すると、ターミナルにアクセス先の URL が表示されます。Local が自分のマシンからアクセスする URL、Network は同じネットワーク上の他の端末からアクセスできる URL です。
▲ Next.js 15.0.0
- Local: http://localhost:3000
- Network: http://192.168.1.10:3000
✓ Ready in 1.8s
止めるときはターミナルで Ctrl + C を押します。開発サーバーはフォアグラウンドで動き続けるので、他のコマンドを打ちたいときは別のターミナルタブを開いてください。
next dev のよく使うオプション
next dev には起動の仕方を変えるオプションがいくつかあります。よく使うものをまとめました。
| オプション | 意味 |
|---|---|
-p, --port | 待ち受けるポート番号を指定する(既定は 3000) |
-H, --hostname | 待ち受けるホスト名を指定する。他の端末からアクセスさせたいときは 0.0.0.0 を指定する |
--turbopack | バンドラーとして Turbopack を使う。起動と再コンパイルが速くなる |
--experimental-https | 自己署名証明書を生成して、ローカルを HTTPS で起動する(実験的機能) |
-h, --help | そのバージョンで使えるオプションの一覧を表示する |
ここで注意したいのは、CLI のオプションは Next.js のバージョンによって名前や既定値が変わることがある点です。とくに Turbopack 関連は変更が入りやすいところなので、手元のプロジェクトで実際に使えるかどうかは npx next dev --help で確認するのが確実です。
# インストールされている Next.js で使えるオプションを確認する
npx next dev --help
ポートを変える(-p / –port)
既定のポート 3000 が他のアプリと衝突する場合や、複数の Next.js プロジェクトを同時に立ち上げたい場合は -p でポートを指定します。
# ポート 4000 で起動する
npx next dev -p 4000
# npm スクリプト経由で渡すときは -- を挟む
npm run dev -- -p 4000
npm run dev -p 4000 と書くと、-p が npm 自身のオプションとして解釈されてしまいます。npm スクリプトの先にある next へ引数を渡したいときは、必ず -- を挟んでください。
PORT 環境変数でポートを指定する
ポート番号は環境変数 PORT でも指定できます。コマンドの前に書けばその実行だけに効きます。
# macOS / Linux
PORT=4000 npm run dev
チーム全員で同じポートを使いたい場合は、package.json の scripts に書き込んでしまうほうが確実です。こうしておけば npm run dev と打つだけで指定したポートで起動します。
{
"scripts": {
"dev": "next dev -p 4000",
"dev:mobile": "next dev -H 0.0.0.0 -p 4000",
"build": "next build",
"start": "next start"
}
}
なお .env.local に PORT=4000 と書いても、ポートの指定としては働きません。.env 系のファイルはアプリのコードから読むための仕組みで、サーバーが起動する前の段階には関与しないためです。ポートはコマンドのオプションか、シェルの環境変数として渡してください。
他の端末からアクセスできるようにする(-H / –hostname)
-H は、サーバーがどのアドレスで接続を受け付けるかを指定するオプションです。localhost(127.0.0.1)だけを待ち受けている状態では、そのマシンの中からしか接続できません。スマートフォンの実機や同じ Wi-Fi につないだ別のパソコンから確認したいときは、0.0.0.0 を指定してすべてのネットワークインターフェースで待ち受けさせます。
# すべてのネットワークインターフェースで待ち受ける
npx next dev -H 0.0.0.0
# ポートと組み合わせる
npx next dev -H 0.0.0.0 -p 4000
起動時に Network の行が表示されているなら、すでに外部からの接続を受け付けている状態です。その場合は -H を付けなくても、表示されている http://192.168.x.x:3000 のような URL にスマホからアクセスできます。この既定の挙動はバージョンによって異なるので、まずは起動時の出力を確認してみてください。
Turbopack を有効にする(–turbopack)
Turbopack は Rust で書かれた Next.js 向けのバンドラーで、開発サーバーの初回起動やファイル変更後の再コンパイルが速くなります。Next.js 15 系では --turbopack フラグで有効にできます。
{
"scripts": {
"dev": "next dev --turbopack",
"build": "next build",
"start": "next start"
}
}
ここもバージョン差が出やすい部分です。以前のバージョンではフラグ名が --turbo でしたし、新しいバージョンでは next dev が最初から Turbopack で動くようになっています。--turbopack を付けて「不明なオプション」と怒られたら、npx next dev --help でそのバージョンの表記を確認するのが早道です。有効になっているかどうかは、起動時のログに Turbopack の表示が出るかどうかで判断できます。
もうひとつ知っておきたいのが、Turbopack は webpack 向けの設定をそのままは引き継がないことです。next.config に webpack のカスタム設定を書いているプロジェクトでは、Turbopack に切り替えた際にその設定が効かず、ビルドが通らないことがあります。既存プロジェクトで試すときは、まず個人の環境で動かしてみて、問題がなければチームに広げるという進め方が安全です。
ローカルを HTTPS で起動する(–experimental-https)
Web の一部の機能は、安全なコンテキスト(HTTPS)でないと動きません。カメラやマイクの取得、位置情報、Service Worker などが該当します。localhost は例外扱いで多くの機能が使えますが、スマホの実機から IP アドレスで開くとその例外が効かず、機能が使えないことがあります。
そうしたときに使えるのが --experimental-https です。自己署名証明書を自動生成して、開発サーバーを HTTPS で起動してくれます。
npx next dev --experimental-https
名前のとおり実験的な機能なので、常用するというより「HTTPS でないと確認できないものがあるとき」に使う位置づけです。自己署名証明書はブラウザが正規のものとして認識しないため、初回アクセス時に警告画面が出ます。開発用と分かったうえで進めてください。
Fast Refresh で保存した内容がすぐ画面に反映される
開発サーバーの価値のほとんどは Fast Refresh にあると言ってもよいでしょう。ファイルを保存すると、変更されたモジュールだけが差し替えられ、画面が更新されます。ページ全体を読み込み直すわけではないので、更新は一瞬です。
ありがたいのは、可能な場合にはコンポーネントの状態(state)が保持されたまま更新されることです。フォームに文字を入力した状態やモーダルを開いた状態のまま、そのコンポーネントの見た目だけを調整できます。毎回操作をやり直さずに済むので、細かい調整の効率が大きく変わります。
ただし常に状態が保たれるわけではありません。React コンポーネント以外のもの(定数や関数など)を export しているファイルを編集した場合や、依存関係の根元にあたるファイルを変更した場合は、ページ全体の再読み込みになります。また、編集の途中で構文エラーになったときはエラーオーバーレイが画面に表示され、直して保存すればそのまま復帰します。「状態が消えたな」と思ったときは、そのファイルが何を export しているかを見直してみてください。
next dev と next build・next start の違い
next dev はあくまで開発用で、本番で動くものとは前提が違います。大きな違いは3つです。
ひとつめは最適化の有無です。開発サーバーはコードをそのまま扱うため、JavaScript は圧縮されておらず、ファイル数もサイズも本番より大きくなります。開発サーバーで測ったページの表示速度は本番の指標にはなりません。
ふたつめはコンパイルのタイミングです。開発サーバーはアクセスされたページをその都度コンパイルします。そのため初めて開くページは少し待たされますが、アプリ全体をビルドする必要がないので起動自体は速くなります。一方 next build はアプリ全体をまとめて検査するので、普段開いていないページの型エラーもそこで初めて表面化します。
みっつめはキャッシュや静的生成の扱いです。本番でビルド時に静的生成されるページも、開発サーバーではリクエストのたびにレンダリングされます。これは変更をすぐ確認するためには都合が良いのですが、「このページは本当に静的化されるのか」を確かめることはできません。本番と同じ挙動を確認したいときは、npm run build してから npm run start で立ち上げてください。デプロイ前の最終確認はこちらで行うのが基本です。
ポート3000が使用中で起動できないとき
開発サーバーでいちばん遭遇しやすいのが、ポートの衝突です。前に起動したプロセスが残っていたり、別のツールが 3000 番を使っていたりすると、起動に失敗するか、意図しないポートで立ち上がります。
別のポートで起動してしまっている
Next.js は 3000 番が使われていると、自動的に次の空きポート(3001 など)で起動することがあります。その場合はターミナルにその旨のメッセージが出ます。「変更したはずなのに反映されない」と悩んでいるとき、実は 3001 で動いている新しいサーバーと、3000 で動き続けている古いサーバーの2つがあって、ブラウザでは古いほうを見ていた、というのはよくある勘違いです。まずは起動ログに表示されている URL を確認してください。
残っているプロセスを終了する
ターミナルを強制終了したときなどは、プロセスだけが残ってポートを掴んだままになることがあります。どのプロセスがポートを使っているかを調べて、終了させましょう。
# 3000 番を使っているプロセスを調べる
lsof -i :3000
# 表示された PID を指定して終了する
kill 12345
# 終了しない場合は強制終了
kill -9 12345
Windows のコマンドプロンプトでは netstat -ano | findstr :3000 で PID を調べ、taskkill /PID 12345 /F で終了させます。どちらの場合も、PID を見誤って関係のないプロセスを落とさないよう、表示されたコマンド名を確認してから実行してください。
そもそもポートを変えてしまう
複数のプロジェクトを並行して触っているなら、プロジェクトごとにポートを決めてしまうのが根本的な解決です。前述のように package.json の dev スクリプトへ -p 4000 のように書き込んでおけば、衝突を気にせず両方を同時に起動できます。API サーバーを別ポートで動かしている構成でも、番号が固定されていると設定を書きやすくなります。
スマホの実機から開発サーバーが開けないとき
実機で表示を確認しようとして、URL を入力しても繋がらない、というのもよくあるつまずきです。原因はいくつかに分かれます。
localhost のまま入力している
localhost は「その端末自身」を指す名前です。スマホのブラウザで http://localhost:3000 を開くと、スマホ自身の 3000 番に接続しようとするため当然つながりません。開発マシンの IP アドレス(http://192.168.1.10:3000 のような形)を入力してください。この URL は開発サーバーの起動時に Network として表示されます。
外部からの接続を受け付けていない
起動ログに Network の行が出ていない場合は、サーバーが localhost だけを待ち受けている状態です。-H 0.0.0.0 を付けて起動し直してください。前述の dev:mobile のように、実機確認用のスクリプトを別に用意しておくと切り替えが楽になります。
ネットワークやファイアウォールで遮られている
2つの端末が同じネットワークにいることも条件です。パソコンは有線 LAN、スマホはゲスト用の Wi-Fi、といった構成だと互いに通信できません。同じ Wi-Fi に接続し直してから試してください。
それでも繋がらないときは、OS のファイアウォールが着信接続をブロックしている可能性があります。macOS ならシステム設定のファイアウォール、Windows なら Windows Defender ファイアウォールの設定で、Node.js の着信接続が許可されているかを確認します。会社や学校のネットワークでは端末どうしの通信自体が禁止されていることもあり、その場合はネットワークの管理者に確認するしかありません。
変更が反映されない・挙動がおかしいとき
ポート以外の原因で「保存したのに変わらない」ということもあります。切り分けの順番を知っておくと早く解決できます。
next.config を編集した
next.config.js や next.config.ts は、開発サーバーの起動時に読み込まれる設定ファイルです。ページのコードと違って保存しただけでは反映されないため、編集したら Ctrl + C で止めて起動し直す必要があります。設定を変えたのに効かない、というときはまずここを疑ってください。環境変数を定義した .env.local も同様に、変更したら再起動が必要です。
.next のキャッシュが壊れている
開発サーバーはコンパイル結果を .next ディレクトリにキャッシュしています。ブランチを大きく切り替えたあとや、依存パッケージを入れ替えたあとなどに、このキャッシュと実際のコードが噛み合わなくなり、不可解なエラーが出ることがあります。.next は自動生成されるディレクトリなので、削除して起動し直せば作り直されます。
# 開発サーバーを止めてから実行する
rm -rf .next
npm run dev
ブラウザ側にキャッシュが残っている
サーバー側は更新されているのに、ブラウザが古いファイルを掴んでいることもあります。まずはスーパーリロード(Windows は Ctrl + Shift + R、macOS は Cmd + Shift + R)を試してください。それでも変わらない場合は、開発者ツールのネットワークタブで「Disable cache」を有効にした状態で開発すると、この種の混乱を避けられます。Service Worker を使っている場合は、アプリケーションタブから登録を解除するのも有効です。
まとめ
next dev は開発サーバーを起動するコマンドで、既定では http://localhost:3000 で待ち受けます。ファイルを保存すると Fast Refresh によって変更が即座に反映され、可能な場合はコンポーネントの状態も保たれたまま更新されます。
ポートを変えたいときは -p 4000 か環境変数 PORT、スマホの実機で確認したいときは -H 0.0.0.0、コンパイルを速くしたいときは --turbopack、HTTPS が必要なら --experimental-https を使います。よく使う組み合わせは package.json の scripts に書いておくと、毎回タイプせずに済みます。CLI のオプションはバージョンによって名前や既定値が変わるので、迷ったら npx next dev --help で手元のバージョンの仕様を確認してください。
起動できないときはポートの衝突、実機から開けないときは待ち受けホストとネットワークをまず疑います。設定ファイルを変えたのに反映されないなら再起動、それでもおかしいなら .next を消してやり直す、という順で切り分けると原因にたどり着きやすくなります。そして開発サーバーは最適化されていない環境なので、本番の表示や速度を確かめたいときは next build と next start を使い分けてください。