はじめに
Web開発を学び始めたときに、まず混乱したのが npm・npx・nvm でした。
チュートリアルを見ると、
npx create-next-app my-app
や
npm install
が当たり前のように出てきます。
さらに調べると
nvm install --lts
というコマンドも登場します。
「結局それぞれ何が違うの?」と思ったので、自分なりに整理してみました。
Node.jsとは
まず前提として、npmやnpxはNode.jsに関連するツールです。
Node.jsは、JavaScriptをブラウザ以外でも実行できる環境です。
例えば以下のようなJavaScriptファイルを実行できます。
console.log("Hello World");
node app.js
ReactやNext.jsなどの開発環境もNode.js上で動いています。
npmとは
npm(Node Package Manager)は、Node.jsに付属しているパッケージ管理ツールです。
簡単に言うと、
ライブラリをインストール・管理するためのツール
です。
例えばReactを追加したい場合は以下のように実行します。
npm install react
すると必要なファイルがダウンロードされ、プロジェクトで利用できるようになります。
よく使うコマンド
npm install
npm run dev
npm run build
npxとは
npxは、パッケージを実行するためのツールです。
npmとの違いは、
インストールせずに実行できる
ことです。
npx create-next-app@latest my-app
必要なタイミングだけ取得して実行してくれます。
nvmとは
nvm(Node Version Manager)は、Node.jsのバージョン管理ツールです。
開発していると、
- プロジェクトAはNode.js 22
- プロジェクトBはNode.js 24
のように、プロジェクトごとに推奨バージョンが異なる場合があります。
そんなときにnvmを利用します。
インストール
nvm install --lts
nvm install 24
バージョン切り替え
nvm use 24
確認
node -v
nvm ls
それぞれの関係
nvm
└─ Node.js を管理
└─ npm が付属
└─ パッケージを管理
└─ npx で実行
| ツール | 役割 |
|---|---|
| nvm | Node.jsのバージョン管理 |
| npm | パッケージの管理 |
| npx | パッケージの実行 |
実際の開発での流れ
nvm install --lts
nvm use --lts
npx create-next-app@latest my-app
npm install axios
npm run dev
開発の構築に必要なpackage.jsonとpackage-lock.jsonについて
package.jsonとは
プロジェクトの設計図みたいなものです。
例
{
"name": "my-app",
"version": "1.0.0",
"scripts": {
"dev": "next dev"
},
"dependencies": {
"react": "^19.0.0",
"next": "^16.2.6"
}
}
書かれているのは主に
- プロジェクト名
- バージョン
- npm scripts
- 使用するライブラリ
"react": "^19.0.0"
はReactの19系を使いたいという意味です。
package-lock.jsonとは
こちらは実際にインストールされたライブラリと、その依存関係のバージョンを記録するファイルです。
例えば package.json が
"react": "^19.0.0"
だとしても、
19.0.1
19.0.2
19.0.3
どれが入るかはタイミングによって変わります。
そこでnpmが
{
"packages": {
"node_modules/react": {
"version": "19.0.2"
}
}
}
みたいにReact 19.0.2を入れましたと記録しておきます。
なぜ必要か?
開発中にインストールしたとします
npm install
一か月後に別PCで
npm install
するとライブラリのバージョンが変わり、これまで動いていたコードが動かなくなる可能性があります。
ですが、package-lock.jsonがあると
React 19.0.2
Next 16.2.6
まで固定されるので、みんな同じ環境になります。なので、同じバージョンのライブラリを利用しやすくなるという利点があります。
npm install と npm ciの違い
npm install は package.json に記載されたパッケージをインストールします。また npm install react のように指定すると新しいパッケージを追加できます。
次にnpm ciとはなんでしょうか、それはpackage-lock.jsonに書いてある通りにインストールするコマンドです
package-lock.jsonというのは、実際にインストールされたライブラリや依存関係のバージョンが固定されて記録されているものです。つまり、既存の開発基準でパッケージをインストールするということです。package.jsonでは時期などによってはバージョンが変動したりします。
npm install
npm install
- package.jsonを見る
- package-lock.jsonも参考にする
- 必要ならlockファイルを更新する
- 柔軟
npm ci
npm ci
- package-lock.jsonを絶対に信じる
- package-lock.jsonとpackage.jsonがずれてたらエラー
- lockファイルを書き換えない
- node_modulesを一旦削除して再構築
なぜnpm ciが必要?
package.jsonには以下のものがある場合があります
{
"react": "^19.0.0"
}
この ^ はメジャーバージョン19の範囲内で利用可能な最新版をインストールしてくださいという意味ですので、
19.0.1
19.0.2
19.1.0
などが違うバージョンが入る可能性があります。
チーム開発では開発環境を同じにしたいため、バージョンを固定化させたいときがあります。
そこで
package-lock.json
に
"react": "19.0.2"
と固定しておくことで
npm ci
で固定バージョンをインストールすることができます。
私は個人開発では npm install を使うことがほとんどで、
npm ci を利用したことはまだありません。
ただし、調べてみると CI/CD 環境やチーム開発では、
package-lock.json を基準に環境を再現するために npm ci が利用されることが多いようです。
まずは「npm install は開発用」「npm ci は環境再現用」と覚えておけば十分です。
npx が node_modules/.bin を見に行く話
実は npx は毎回インターネットからパッケージを取得しているわけではありません。
まず現在のプロジェクト内にある
node_modules/.bin
を探し、実行可能なコマンドが存在するか確認します。
例えば eslint がインストールされている場合、
npx eslint .
を実行すると、プロジェクト内の eslint が利用されます。
そのためグローバルインストールに依存せず、
プロジェクトごとに同じバージョンのツールを利用できます。
もしコマンドが見つからない場合は、npmレジストリから取得して実行します。
初心者のうちは
「npx = ツールを実行するためのコマンド」
と覚えておけば十分です。
内部的にはまず node_modules/.bin を探していることを知っておくと理解が深まります。
nvmを使う理由(Nodeバージョン事故防止)
Node.jsは定期的に新しいバージョンがリリースされます。
しかしプロジェクトによっては特定のNode.jsバージョンでしか正常に動作しないことがあります。
例えば、
- プロジェクトA → Node.js 22
- プロジェクトB → Node.js 24
のようなケースです。
Node.jsを直接インストールしていると切り替えが大変ですが、nvmを利用すると簡単にバージョンを切り替えられます。
そのためチーム開発や複数プロジェクトを扱う場合によく利用されます。
LTSとは
LTS(Long Term Support)は長期サポート版のことです。
Node.jsには最新機能を試せるCurrent版と、安定性を重視したLTS版があります。
通常の開発ではLTS版を利用することが推奨されています。
そのためNode.jsをインストールするときは、
nvm install --lts
を利用することが多いです。
最初に覚えるならこれだけ
- nvm → Node.jsを管理する
- npm → ライブラリを管理する
- npx → ツールを実行する
私自身、最初は違いが分からず混乱していましたが、実際に使いながら覚えることで少しずつ理解できるようになりました。
これからReactやNext.jsを学ぶ方の参考になれば幸いです。
補足:パッケージ管理で気をつけたいこと
npmでは外部パッケージを簡単に導入できますが、
過去には有名ライブラリがサプライチェーン攻撃の対象になった事例もあります。詳しくは「Axios サプライチェーン攻撃」で検索してみてください。
そのため実務では、
- package-lock.json をGit管理する
- npm ci を利用する
- 信頼できるパッケージを利用する
- 不要な依存関係を増やしすぎない
といった対策が重要です。