If npm install -g @openai/codex fails before Codex CLI is ever installed, you will see one of these:
npm error code EACCES
npm error syscall mkdir
npm error path /usr/local/lib/node_modules/@openai
npm error errno -13
npm error Error: EACCES: permission denied, mkdir '/usr/local/lib/node_modules/@openai'
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
On npm 9 and earlier the same failure is printed with the older prefix:
npm ERR! code EACCES
npm ERR! syscall mkdir
npm ERR! path /usr/local/lib/node_modules/@openai
npm ERR! errno -13
npm ERR! Error: EACCES: permission denied, mkdir '/usr/local/lib/node_modules/@openai'
Same cause, same fix. This guide resolves it without sudo, then deals with the "command not found" error that frequently follows.
Why This Happens
npm install -g writes into npm's global prefix. Check yours:
npm config get prefix
If that prints /usr/local or /usr, the directories npm needs to write — lib/node_modules, bin, share — are owned by root. npm itself is running as you. The very first step of installing a scoped package is creating the scope directory @openai, that mkdir is rejected by the OS, and npm reports errno -13 (EACCES).
This is not specific to Codex. It affects every global npm install on a system where Node was installed from the nodejs.org .pkg installer, from apt-get install nodejs, or from any method that places Node under a root-owned prefix.
Fix 1: Move the Global Prefix to a Directory You Own
This is the fix that works on every platform and survives Node upgrades.
# 1. Create a user-owned directory for global packages
mkdir -p ~/.npm-global
# 2. Tell npm to use it
npm config set prefix ~/.npm-global
# 3. Add its bin directory to PATH (zsh — the macOS default)
echo 'export PATH="$HOME/.npm-global/bin:$PATH"' >> ~/.zshrc
source ~/.zshrc
# 4. Install Codex CLI — no sudo
npm install -g @openai/codex
# 5. Confirm
codex --version
If your shell is bash, use ~/.bashrc (Linux) or ~/.bash_profile (macOS) in step 3 instead of ~/.zshrc.
Fix 2: Use a Node Version Manager
If you expect to install more global CLIs, install Node through a version manager. Both nvm and fnm place Node and its global node_modules inside your home directory, so the permission problem cannot recur.
# nvm
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.1/install.sh | bash
exec $SHELL
nvm install 22
nvm use 22
npm install -g @openai/codex
codex --version
Codex CLI ships prebuilt binaries as optional dependencies per platform, so make sure the install completes rather than being interrupted. A truncated install produces a different error on first run:
Missing optional dependency @openai/codex-linux-x64. Reinstall Codex: npm install -g @openai/codex
Re-running the install with a working network connection resolves that.
Fix 3: Homebrew Node (macOS)
On Apple Silicon, Homebrew installs into /opt/homebrew, which is owned by your user account, so the global prefix is already writable:
brew install node
npm config delete prefix # drop any earlier override
npm install -g @openai/codex
codex --version
On Intel Macs Homebrew uses /usr/local, which it also chowns to your user during setup, so the same applies.
Fix 4: Take Ownership of the Existing Prefix
If you would rather keep the current prefix, npm's documented alternative is to change its owner:
sudo chown -R $(whoami) $(npm config get prefix)/{lib/node_modules,bin,share}
npm install -g @openai/codex
This works, but a Node upgrade that recreates those directories can re-introduce root ownership. Prefer Fix 1 or Fix 2 for a machine you use daily.
Why Not Just Use sudo
sudo npm install -g @openai/codex usually appears to work, and it is the reason many people hit EACCES again a week later. It causes three problems:
- Files land in
~/.npm(your cache) owned byroot, so your next non-sudonpm installfails with EACCES on the cache instead of the prefix. - Package lifecycle scripts execute as root.
- The installed binary may not be readable or executable by your user in the way you expect.
If you have already run a sudo install, reset the cache ownership before continuing:
sudo chown -R $(whoami) ~/.npm
Windows
Windows reports this as EPERM or EACCES on a path under %AppData%\npm or C:\Program Files\nodejs. Two working approaches:
# Option A: elevate for the install only
# (right-click PowerShell -> Run as Administrator)
npm install -g @openai/codex
codex --version
# Option B (preferred): nvm-windows, which installs under your user profile
nvm install 22
nvm use 22
npm install -g @openai/codex
If the file is locked rather than permission-denied, close any editor or terminal that has Node running and retry.
If npm is not the problem and the standalone installer is the one failing — with Could not find Codex package or platform npm release assets for Codex — see that installer error; switching to npm is one of its documented workarounds.
The Follow-On Error: "codex: command not found"
After you change the prefix, the install succeeds but the shell may still report:
zsh: command not found: codex
The binary exists; your PATH does not include the new prefix's bin directory. Confirm the location and fix PATH:
# Where did it actually install?
npm config get prefix # e.g. /Users/you/.npm-global
ls $(npm config get prefix)/bin/codex
# Add it permanently — substitute the real path, do not leave a command
# substitution in your profile or every new shell will run npm on startup
echo 'export PATH="$HOME/.npm-global/bin:$PATH"' >> ~/.zshrc
source ~/.zshrc
# zsh caches command locations — clear it if the path is right but the error persists
hash -r
Then open a new terminal window and run codex --version.
Verify the Fix
npm config get prefix # a path inside your home directory
npm ls -g --depth=0 # should list @openai/codex
which codex # resolves to <prefix>/bin/codex
codex --version # prints the installed version
If all four succeed, authenticate and you are done:
codex
Prevent It Coming Back
- Never install global npm packages with
sudo. - Keep
npm config get prefixpointing inside your home directory, or manage Node withnvm/fnm. - Put the PATH export in your shell profile, not just the current session, so new terminals inherit it.
- After a major Node upgrade, re-run
npm config get prefixandwhich codex— an upgrade can reset both.
Next Steps
- Install Codex CLI for full platform-by-platform setup
- Where Codex configuration files are stored
- Fix "Unable to locate the Codex CLI binary" if the desktop app cannot find a CLI you have installed