npm install が EACCES(permission denied)で失敗する
グローバル install で /usr/local や /usr/lib への書き込み権限が無いと EACCES になる。
sudo に頼らず npm の prefix をユーザー領域に張り直すか、nvm / fnm で Node 自体を入れ直すのが安全策。
公開: 更新:
要約
npm install -g で EACCES: permission denied が出るのは、グローバル prefix が システム所有のディレクトリ を指しているため。sudo npm で逃げると ~/.npm の所有権が root に汚染され、後の通常 install まで巻き添えで失敗するようになる。
安全策は prefix をユーザー領域に張り直す か、nvm / fnm / volta で Node 自体をユーザー領域に入れ直す こと。
よくある原因
- prefix がシステム領域:
npm config get prefixの出力が/usr/localなど root 所有を指す - sudo install の副作用: 過去に
sudo npm i -gを打ち、~/.npmの所有権が root になっている - OS パッケージ製の Node: apt / yum / Homebrew で入れた Node はシステム配下に書き込もうとする
- 共有 node_modules: 別ユーザーで作られたディレクトリに今のユーザーで書き込もうとしている
解決策
1. prefix をユーザー領域に張り直す
mkdir -p ~/.npm-global
npm config set prefix '~/.npm-global'
echo 'export PATH=~/.npm-global/bin:$PATH' >> ~/.bashrc
source ~/.bashrc
npm install -g <pkg>公式の手順(新しいタブで開く) に沿った最小構成。npm config get prefix で反映を確認する。
2. nvm / fnm / volta で入れ直す
# nvm の例
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.1/install.sh | bash
nvm install --lts
nvm use --ltsホームディレクトリ以下に Node が入るため、グローバル install もすべて書き込み権限のある場所に向く。fnm / volta も方針は同じ。
3. キャッシュの所有権を戻す
sudo chown -R $(whoami) ~/.npm過去に sudo を踏んでしまった場合の応急処置。
これを忘れると新 prefix に切り替えても EACCES が再発することがある。
4. sudo install を巻き戻す
sudo npm uninstall -g <pkg>
npm install -g <pkg> # 新 prefix に入れ直す以後 sudo npm を使わない方針に切り替える。
grep で履歴に残っていないかも確認しておく。
実行例
実際に上記の手順を node:20(Debian GNU/Linux 12 bookworm)環境で動かすと、一般ユーザー(nobody)による npm install -g は /usr/local/lib/node_modules への mkdir を拒否されて EACCES(終了コード 243)で失敗し、prefix をユーザー領域(~/.npm-global)に張り直すことで終了コード 0 での成功まで再現できた。
$ node -v
v20.20.2$ npm -v
10.8.2$ npm config get prefix
/usr/local$ ls -ld /usr/local/lib/node_modules
drwxr-xr-x 4 root root 4096 Mar 24 03:03 /usr/local/lib/node_modules$ npm install -g is-number@7
npm error code EACCES
npm error syscall mkdir
npm error path /usr/local/lib/node_modules/is-number
npm error errno -13
npm error Error: EACCES: permission denied, mkdir '/usr/local/lib/node_modules/is-number'
npm error at async mkdir (node:internal/fs/promises:856:10)
npm error at async /usr/local/lib/node_modules/npm/node_modules/@npmcli/arborist/lib/arborist/reify.js:624:20
npm error at async Promise.allSettled (index 0)
npm error at async [reifyPackages] (/usr/local/lib/node_modules/npm/node_modules/@npmcli/arborist/lib/arborist/reify.js:325:11)
npm error at async Arborist.reify (/usr/local/lib/node_modules/npm/node_modules/@npmcli/arborist/lib/arborist/reify.js:142:5)
npm error at async Install.exec (/usr/local/lib/node_modules/npm/lib/commands/install.js:150:5)
npm error at async Npm.exec (/usr/local/lib/node_modules/npm/lib/npm.js:207:9)
npm error at async module.exports (/usr/local/lib/node_modules/npm/lib/cli/entry.js:74:5) {
npm error errno: -13,
npm error code: 'EACCES',
npm error syscall: 'mkdir',
npm error path: '/usr/local/lib/node_modules/is-number'
npm error }
npm error
npm error The operation was rejected by your operating system.
npm error It is likely you do not have the permissions to access this file as the current user
npm error
npm error If you believe this might be a permissions issue, please double-check the
npm error permissions of the file and its containing directories, or try running
npm error the command again as root/Administrator.
npm error A complete log of this run can be found in: /tmp/recipe-home/.npm/_logs/2026-08-02T08_45_55_340Z-debug-0.log
終了コード: 243$ npm config set prefix ~/.npm-global$ npm config get prefix
/tmp/recipe-home/.npm-global$ npm install -g is-number@7
added 1 package in 528ms
終了コード: 0$ ls ~/.npm-global/lib/node_modules
is-number
終了コード: 0— 2026-08-02 時点の出力