Apple Silicon broke every JavaScript setup guide that worked on Intel. Here's what you're walking into: a maze of ARM64 vs x86 binaries, shell configuration hell, and error messages that make no fucking sense.
Apple Silicon: Fast Computer, Slow JavaScript Setup
Your M1/M2/M3 Mac compiles C++ 3x faster than Intel but somehow takes longer to set up a JavaScript development environment. Node.js v16+ has native ARM64 binaries, but legacy dependencies written when Obama was president will crash harder than my hopes of finishing this tutorial in under an hour.
Here's what I learned migrating 15 projects from Intel to Apple Silicon: Node 18+ runs beautifully once you get it working. Node 14 and below require either Rosetta 2 or compiling from source, which takes 45 minutes when the stars align and fails spectacularly when they don't. I've literally watched native ARM64 Node.js compile TypeScript 40% faster than the same code on my old Intel MacBook Pro, but only after spending 4 hours debugging why npm-gyp couldn't find Python.
First Things First: Command Line Tools (The Hidden Dependency)
You need Xcode Command Line Tools before touching NVM. Apple removed git from the base system, and NVM's install script needs it to clone the repository. I learned this the hard way when the installer failed with a cryptic curl error code 22.
xcode-select --install
You'll get a popup asking to install the tools. Click "Install" and wait. If you see command line tools are already installed
, you're set. Otherwise, this downloads ~200MB and installs for 10-15 minutes. The progress bar will sit at 90% for what feels like forever - this is normal. Don't cancel it.
Shell Configuration Hell (Choose Your Fighter)
macOS Catalina switched from bash to zsh but left behind a trail of conflicting config files. NVM supports zsh and bash. Fish shell users are out of luck - NVM has never supported fish and probably never will, though there's nvm.fish as an alternative.
The installer needs to know which shell profile to modify. Most people have multiple config files cluttering their home directory from years of copying random solutions from Stack Overflow. NVM picks the "first" one it finds, which isn't always the right one.
Shell profile locations:
- zsh (default):
~/.zshrc
- create it withtouch ~/.zshrc
if missing - bash:
~/.bash_profile
or~/.bashrc
- depends on your terminal configuration - other shells: Check NVM's installation docs
I've debugged systems where someone had both .bashrc
and .zshrc
, NVM picked .bashrc
, but Terminal was running zsh. Result: nvm: command not found
forever.
Network Requirements (Where Everything Goes Wrong)
Corporate networks are the enemy of JavaScript developers. GitHub's raw.githubusercontent.com gets blocked by overzealous firewalls, nodejs.org downloads get flagged as suspicious, and SSL certificates fail in spectacular ways.
I've seen NVM installations fail because:
- Corporate proxy strips SSL certificates - curl fails with SSL_ERROR_SYSCALL
- DNS resolution fails for github.com - returns "could not resolve host"
- VPN routes traffic through servers that hate JavaScript developers
- Company firewall blocks anything with "node" in the URL - returns 403 Forbidden on downloads
- GitHub raw content blocked by corporate firewalls - the most common issue
If downloads hang or SSL fails, disconnect from VPN temporarily. Your IT department might not understand, but your deadline won't wait.
Node.js Version Compatibility on Apple Silicon (The Painful Truth)
Node Version | ARM64 Support | Install Time | Reality Check |
---|---|---|---|
v24.x Current | Native ARM64 | 30 seconds | Latest features, bleeding edge bugs |
v22.x LTS "Jod" | Native ARM64 | 30 seconds | Current LTS (July 2025), production stable |
v20.x LTS "Iron" | Native ARM64 | 30 seconds | Maintenance mode, still solid |
v18.x Legacy LTS | Native ARM64 | 30 seconds | EOL April 2025, upgrade soon |
v16.x-v17.x | Native ARM64 | 30 seconds | EOL, works but no security updates |
v14.17+ | Source compile only | 45+ minutes | Usually fails, use Rosetta instead |
< v14.17 | Rosetta 2 required | Variable | Time machine to 2020, just upgrade |
The key insight: Node.js started shipping native ARM64 binaries with v16.0.0. Anything older requires either compiling from source (painful) or running Intel binaries through Rosetta (slower).
Clean Up Your Existing Node Mess
If you already have Node installed, you have three options:
- Keep the chaos: Live with version conflicts and PATH issues
- Nuke everything: Remove all Node installations and start fresh
- Pray it works: Install NVM alongside existing Node and debug for hours
For the nuclear option:
## Remove Homebrew Node (if you have it)
brew uninstall node --ignore-dependencies
## Remove official Node installer remnants
sudo rm -rf /usr/local/{bin/{node,npm},lib/node_modules/npm,lib/node,share/man/*/node.*}
## Clean any previous NVM installation
rm -rf ~/.nvm
Never install NVM through Homebrew. The official NVM docs explicitly warn against it because it creates conflicting installations. Homebrew's NVM formula is community-maintained and breaks in ways that'll make you question your life choices.
Pre-Installation System Check
Run these commands to see what you're working with (and to document your starting point before everything goes wrong):
## Check you're on Apple Silicon
uname -m
## Better show: arm64
## If you see x86_64, you're on Intel (wrong guide)
## Check macOS version
sw_vers -productVersion
## Should be 11.0+, but honestly anything recent works
## Monterey (12.x) and Ventura (13.x) are tested and stable
## Check disk space
df -h ~
## NVM needs ~50MB, each Node version adds ~80MB
## Budget 1GB if you're a version hoarder like most of us
## Check existing Node installations (know thy enemy)
which node
which npm
## If these return system paths, prepare for conflicts
## Check current shell (this matters for config files)
echo $SHELL
## Should show /bin/zsh on modern macOS
Pro tip: Copy this output somewhere. When things break (they will), you'll want to compare "before" vs "after" states.
Should take 5 minutes. Budget 2 hours for debugging because nothing in Apple Silicon development works the first time.