XVM: Xcode Version Manager - No More Headaches When New Xcode Drops
Опубликовано 05 октября 2025 AntonSeagull — 4 min
XVM: When New Xcode Drops, Everything Goes Sideways
Hey there, fellow developers! Today I want to tell you about utility XVM (Xcode Version Manager) and why it should be in every iOS developer's toolkit.
The Problem We All Know Too Well
You know that moment when Apple releases a new Xcode, but your project still uses an older iOS SDK? Or when a client asks you to build a project with Xcode 15.4, but you already have 16.2 installed?
That's when the classic headache begins:
- Download the required Xcode version (8+ gigabytes, thanks Apple)
- Rename the current Xcode to
Xcode-16.2.app
- Rename the new one to
Xcode.app
- Run
sudo xcode-select --switch /Applications/Xcode.app
- Wait for Xcode to re-index all projects
- Pray that nothing breaks
And a week later you need to switch back, and this whole circus repeats. Sound familiar? Then keep reading.
The Solution: XVM
XVM is a simple command-line utility that automates this entire process. Set up multiple Xcode versions once, and now you can switch between them with a single command.
What XVM can do:
- Show all installed Xcode versions —
xvm list
- Show current active version —
xvm current
- Switch between versions —
sudo xvm switch 15.4
- Dry-run mode —
xvm switch 15.4 --dry-run
- Bilingual interface — works in Russian and English
Installation
Quick install (recommended):
curl -sSL https://raw.githubusercontent.com/AntonSeagull/xcode-version-manager/main/install-xvm.sh | bash
Manual installation:
- Download the latest binary from releases
- Make it executable:
chmod +x xvm-darwin-amd64
(orxvm-darwin-arm64
for Apple Silicon) - Move to PATH:
sudo mv xvm-darwin-amd64 /usr/local/bin/xvm
How it works
XVM manages Xcode versions very elegantly:
- Renames the current active Xcode (usually
/Applications/Xcode.app
) to a versioned name (e.g.,Xcode-16.2.app
) - Renames the target Xcode (e.g.,
Xcode-15.4.app
) to/Applications/Xcode.app
- Updates xcode-select to point to the new active version
Simple and clear. No magic, just common sense.
Usage Examples
# List all versions
xvm list
# Active / Active: /Applications/Xcode.app (16.2)
#
# Found in /Applications:
# * /Applications/Xcode.app (16.2)
# /Applications/Xcode-15.4.app (15.4)
# /Applications/Xcode-14.3.1.app (14.3.1)
# Switch to Xcode 15.4
sudo xvm switch 15.4
# Preview switch
xvm switch 14.3.1 --dry-run
Setting up multiple Xcode versions
- Download Xcode versions from Apple Developer Downloads
- Install each version to
/Applications/
with a versioned name:Xcode-16.2.app
Xcode-15.4.app
Xcode-14.3.1.app
- Use XVM to switch between them
Why do you need this?
For development teams:
- Everyone works on the same Xcode versions
- Easy switching between projects with different requirements
- Less "it works on my machine" situations
For CI/CD:
- Test on different Xcode versions
- Automate version switching in scripts
For legacy project support:
- Old projects that don't compile on newer versions
- Clients who require a specific Xcode version
Requirements
- macOS (tested on macOS 10.15+)
- Multiple Xcode installations in
/Applications/
directory - Administrator privileges for switching versions (sudo required)
Commands Reference
Command | Description |
---|---|
xvm list |
Show all installed Xcode versions |
xvm current |
Show currently active Xcode version |
xvm switch <version> |
Switch to specified version |
xvm switch <version> --dry-run |
Preview switch operation |
Troubleshooting
Permission denied
Make sure you're using sudo
when switching versions:
sudo xvm switch 15.4
Xcode not found
Ensure your Xcode installations are named correctly:
ls -la /Applications/Xcode*
Should show files like /Applications/Xcode-16.2.app
, /Applications/Xcode-15.4.app
, etc.
Version detection issues
XVM tries multiple methods to detect Xcode versions:
- Reading Info.plist
- Using xcodebuild -version
Conclusion
XVM solves a real problem that every iOS developer faces. No more dancing around when switching Xcode versions. One command and you're done.
Try it yourself and let me know if something doesn't work. The source code is open, report bugs in GitHub Issues.
P.S. If you have ideas for improvements or want to add new features — welcome to contribute! 🚀