sudo xcode-select -s /Applications/Xcode.app/Contents/Developer, or pick your Xcode in Xcode > Settings > Locations, then re-run the failing command.Why this happens
macOS stores one machine-wide pointer that tells every command line tool which developer folder to use. You can print it at any time:
xcode-select -p
There are only two realistic values. One is the Developer folder inside a full Xcode install, normally /Applications/Xcode.app/Contents/Developer. The other is the standalone Command Line Tools package at /Library/Developer/CommandLineTools.
When that pointer sits on the Command Line Tools folder, anything that shells out to xcodebuild stops with:
xcode-select: error: tool 'xcodebuild' requires Xcode, but active developer directory '/Library/Developer/CommandLineTools' is a command line tools instance
The usual trigger is installing the standalone Command Line Tools after Xcode is already on the machine — for example by running xcode-select --install, by a Homebrew or CI setup script, or by a macOS upgrade that refreshes the tools. The install flips the pointer to the lighter package, and the next build that needs a real Xcode fails.
npm install is the most common victim because node-gyp compiles native addons and calls xcodebuild to discover SDKs and build settings. The same error shows up from Homebrew formulae that compile from source, Ruby gems with native extensions, and any build script that runs xcodebuild directly.
How to fix it
1. Point xcode-select back at Xcode.app
Check where the pointer currently is, confirm Xcode is actually installed, then switch it:
xcode-select -p
ls -d /Applications/Xcode*.app
sudo xcode-select -s /Applications/Xcode.app/Contents/Developer
xcode-select -p
The last command should now print /Applications/Xcode.app/Contents/Developer. Verify that the toolchain answers:
xcodebuild -version
Two details matter here. The path must end in Contents/Developer — pointing at the .app bundle itself is not valid. And -s is the short form of --switch; both work.
If Xcode lives somewhere else, use that path instead. A renamed copy such as Xcode 27.app or a beta in /Applications/Xcode-beta.app needs its own path:
sudo xcode-select -s /Applications/Xcode-beta.app/Contents/Developer
If Xcode has never been launched, macOS may ask you to accept the license before xcodebuild runs. Do that with:
sudo xcodebuild -license accept
Then re-run the command that failed. If npm cached a broken native build, clear it with npm rebuild or by deleting node_modules and installing again.
2. Use Xcode’s own Locations setting
You do not have to remember the path. Open Xcode, then go to Settings → Locations (called Preferences → Locations in older versions) and use the Command Line Tools popup to select your Xcode version. This writes the same pointer without needing sudo, and it is the safest option when several Xcodes are installed.
If the popup is empty or greyed out, Xcode has not finished its first-launch component install. Let it complete, or run:
sudo xcodebuild -runFirstLaunch
3. Reset to the default
If Xcode is in /Applications under its standard name, you can let macOS pick it automatically:
sudo xcode-select --reset
xcode-select -p
This clears any custom selection and falls back to the default developer directory. It is a quick recovery after a macOS update, but it will not help if Xcode is installed elsewhere or renamed — use -s with the real path in that case.
4. Override the directory for a single command
Sometimes you do not want to change the machine-wide setting — a CI job, a one-off build, or a colleague’s Mac. Every tool that respects xcode-select also respects the DEVELOPER_DIR environment variable:
DEVELOPER_DIR=/Applications/Xcode.app/Contents/Developer npm install
This applies only to that process and its children, so the rest of the system keeps its current selection. It is the cleanest way to pin a specific Xcode in a build script.
5. If you only have Command Line Tools installed
Running xcode-select --install again will not fix this error — it installs the Command Line Tools package, which is exactly the thing the pointer is already aimed at. Tools that call xcodebuild need the full Xcode app. Install it from the App Store or from Apple’s developer downloads, move it to /Applications, launch it once, accept the license, then switch the pointer as shown above.
How to prevent it
- After installing or updating Command Line Tools, run
xcode-select -pand confirm it still points at Xcode. - Keep Xcode in
/Applicationswith its default name so--resetand Xcode’s own Locations popup keep working. - Prefer Xcode → Settings → Locations over hand-typed paths; it cannot point at a folder that does not exist.
- In CI and build scripts, set
DEVELOPER_DIRexplicitly instead of relying on whatever the machine was last configured with. - Avoid running
xcode-select --installon a Mac that already has Xcode unless you actually need the standalone tools.
FAQ
Do I really need the full Xcode app just to run npm install?
Only when a dependency contains native code. node-gyp compiles that code and calls xcodebuild, which the standalone Command Line Tools package cannot satisfy. Pure JavaScript packages install fine without Xcode.
Why did this appear right after a macOS update?
System updates can reinstall or refresh the Command Line Tools and leave the developer directory pointing at them. Checking xcode-select -p and switching back to Xcode takes a few seconds.
What is the difference between xcode-select --install and xcode-select -s?
--install downloads and installs the standalone Command Line Tools package. -s (or --switch) changes which developer directory is active. The first one caused your problem; the second one fixes it.
Parts of this guide are adapted from content licensed under CC BY-SA 3.0; this article is shared under the same license.
