What is the Best Way to Install Node.js on Windows for React Development?
The Problem: When npm create vite Fails Mysteriously
I spent three hours trying to figure out why npm create vite@latest kept failing on my Windows machine. The error messages were cryptic:
npm ERR! code EPERMnpm ERR! syscall mkdirnpm ERR! path C:\Program Files\nodejs\node_modules\npm\npxnpm ERR! errno -4048npm ERR! Error: EPERM: operation not permitted, mkdir 'C:\Program Files\nodejs\node_modules\npm\npx'npm ERR! [Error: EPERM: operation not permitted, mkdir 'C:\Program Files\nodejs\node_modules\npm\npx'] {npm ERR! errno: -4048,npm ERR! code: 'EPERM',I had installed Node.js via Chocolatey. It seemed convenient at the time—one command and done:
choco install nodejsBut I didn’t realize Chocolatey installs Node.js under Program Files with SYSTEM PATH modifications. This causes permission conflicts when npm tries to write to its cache or when npx needs to create temporary files.
Running the terminal as Administrator? That made things worse—now some packages install with elevated permissions, causing more permission issues later when I run npm as a regular user.
I needed a better solution.
Why the Official Installer Also Falls Short
Before Chocolatey, I tried the official Node.js installer from nodejs.org. It works fine for a single Node.js version. But here’s the problem: different React projects often require different Node.js versions.
Project A needs Node.js 18. Project B requires Node.js 20 for React 19 compatibility. With the official installer, I had to:
- Download the old version’s uninstaller
- Uninstall the current Node.js
- Download the new version’s installer
- Install the new version
- Reinstall all global npm packages
This tedious cycle repeated every time I switched projects. There had to be a better way.
The Solution: Version Managers for Windows
After digging through Reddit threads and official documentation, I found the answer: use a Node.js version manager. Version managers solve both problems:
- No permission issues: They install Node.js in user directories, not
Program Files - Instant version switching: One command changes the active Node.js version
The Node.js documentation itself recommends version managers when you need to switch between versions for different projects.
Option 1: nvm-windows (Most Popular)
nvm-windows is recommended by Microsoft, npm, and Google. It uses a symlink mechanism instead of directly modifying PATH, which is more reliable across console windows and reboots.
First, I had to uninstall the Chocolatey-installed Node.js:
choco uninstall nodejsIf you used the official installer, uninstall via Windows Settings > Apps > Installed apps > Node.js.
Then download nvm-windows from the GitHub releases page and run the installer.
Now I can install and switch between Node.js versions easily:
# Install the LTS versionnvm install lts
# Install a specific versionnvm install 20.11.0
# List installed versionsnvm list
# Switch to a versionnvm use 20.11.0Important caveat: Global npm modules are not shared between Node.js versions. When you switch versions, you’ll need to reinstall any global packages you need:
nvm use 18npm install -g pnpmnpm install -g @anthropic-ai/claude-codeOption 2: fnm (Fastest)
fnm is built in Rust, making it significantly faster than nvm-windows. It supports Windows via multiple installation methods:
winget install Schniz.fnmOr with Scoop:
scoop install fnmOr even with Chocolatey (ironic, but fnm manages itself well):
choco install fnmAfter installation, you need to set up your shell. For PowerShell, run:
fnm env --use-on-cd | Out-String | Invoke-ExpressionAdd this to your PowerShell profile for persistence.
Using fnm is straightforward:
# Install LTSfnm install --lts
# Install specific versionfnm install 20.11.0
# Use a versionfnm use 20.11.0
# Set defaultfnm default 20.11.0fnm also supports .nvmrc and .node-version files automatically, so it switches versions when you cd into a project directory.
Option 3: mise (Modern All-in-One)
mise is what I eventually settled on. It’s a drop-in replacement for nvm but also manages other languages like Python, Ruby, and Go. If you work with multiple languages, mise is compelling.
Install mise on Windows:
winget install jdx.miseOr with Scoop:
scoop install miseActivate mise in your shell:
mise activate pwsh | Out-String | Invoke-ExpressionUsing mise for Node.js:
# Install Node.js LTSmise use node@lts
# Install specific version
# List installed versionsmise lsmise can also auto-install default npm packages with each new Node.js version by configuring your ~/.config/mise/config.toml:
[tools]node = "lts"
[settings.node]default_packages = [ "pnpm", "@anthropic-ai/claude-code",]Option 4: Volta (Hassle-Free)
Volta takes a different approach—it manages not just Node.js but your entire JavaScript toolchain including npm, yarn, and pnpm. It’s designed to be “hassle-free” with zero configuration needed.
Install Volta:
winget install Volta.VoltaVolta automatically pins Node.js versions per project:
# Install Node.jsvolta install node
# Pin a version for the current projectThe Result: No More Permission Issues
After switching to mise, my Vite project creation works flawlessly:
npm create vite@latest my-react-appcd my-react-appnpm installnpm run devNo EPERM errors. No permission denied. No need to run as Administrator.
The key insight is this: version managers install Node.js in user-writable directories (like ~/.local/share/mise/installs/node/... or ~/.nvm/versions/node/...), avoiding the Windows permission model problems that plague installations in Program Files.
Project-Level Version Locking
One feature I now consider essential is the ability to lock Node.js versions per project. With mise, I create a .node-version file in my project root:
20.11.0Or with .nvmrc format:
v18.19.0When I cd into the project directory, mise automatically switches to the correct Node.js version. This ensures all team members use the same version, eliminating “works on my machine” issues.
For React projects, this is particularly important. React 19 requires Node.js 18+. Some older React projects might require Node.js 16. With version locking, I never have to think about it—the correct version is always active.
Common Mistakes to Avoid
-
Not uninstalling existing Node.js first: nvm-windows specifically requires this. Having both installed causes PATH conflicts.
-
Running terminals as Administrator: This causes permission issues with npm when you later run as a regular user. Install and use Node.js from a regular user terminal.
-
Forgetting to reinstall global packages: Each Node.js version has its own set of global packages. After switching versions, reinstall what you need.
-
Not committing version files: Add
.nvmrcor.node-versionto your repository so team members use the same Node.js version. -
Mixing installation methods: Don’t use Chocolatey to install Node.js if you’re using a version manager. Let the version manager handle everything.
Final Recommendation
For React development on Windows, I recommend:
- Beginners: Use nvm-windows. It’s the most documented and widely used.
- Performance-focused: Use fnm. It’s the fastest option.
- Polyglot developers: Use mise. It manages Node.js, Python, Rust, Go, and more.
- JavaScript-only developers: Use Volta. It manages your entire JS toolchain.
All of these options are vastly superior to Chocolatey or the official installer for active development work. The time I spent debugging Vite errors could have been avoided entirely with a proper version manager from the start.
Final Words + More Resources
My intention with this article was to help others share my knowledge and experience. If you want to contact me, you can contact by email: Email me
Here are also the most important links from this article along with some further resources that will help you in this scope:
- 👨💻 Node.js Official Downloads
- 👨💻 nvm-windows GitHub Repository
- 👨💻 fnm - Fast Node Manager
- 👨💻 Volta - Hassle-free JavaScript Tool Manager
- 👨💻 mise Node.js Documentation
- 👨💻 Vite Getting Started Guide
Oh, and if you found these resources useful, don’t forget to support me by starring the repo on GitHub!
Comments