Skip to content

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:

Vite creation error
npm ERR! code EPERM
npm ERR! syscall mkdir
npm ERR! path C:\Program Files\nodejs\node_modules\npm\npx
npm ERR! errno -4048
npm 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:

Installing Node.js via Chocolatey
choco install nodejs

But 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:

  1. Download the old version’s uninstaller
  2. Uninstall the current Node.js
  3. Download the new version’s installer
  4. Install the new version
  5. 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:

  1. No permission issues: They install Node.js in user directories, not Program Files
  2. 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.

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:

Uninstalling Node.js via Chocolatey
choco uninstall nodejs

If 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:

Using nvm-windows
# Install the LTS version
nvm install lts
# Install a specific version
nvm install 20.11.0
# List installed versions
nvm list
# Switch to a version
nvm use 20.11.0

Important 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:

Reinstalling global packages after version switch
nvm use 18
npm install -g pnpm
npm install -g @anthropic-ai/claude-code

Option 2: fnm (Fastest)

fnm is built in Rust, making it significantly faster than nvm-windows. It supports Windows via multiple installation methods:

Installing fnm via winget
winget install Schniz.fnm

Or with Scoop:

Installing fnm via Scoop
scoop install fnm

Or even with Chocolatey (ironic, but fnm manages itself well):

Installing fnm via Chocolatey
choco install fnm

After installation, you need to set up your shell. For PowerShell, run:

fnm PowerShell setup
fnm env --use-on-cd | Out-String | Invoke-Expression

Add this to your PowerShell profile for persistence.

Using fnm is straightforward:

Using fnm
# Install LTS
fnm install --lts
# Install specific version
fnm install 20.11.0
# Use a version
fnm use 20.11.0
# Set default
fnm default 20.11.0

fnm 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:

Installing mise via winget
winget install jdx.mise

Or with Scoop:

Installing mise via Scoop
scoop install mise

Activate mise in your shell:

mise PowerShell setup
mise activate pwsh | Out-String | Invoke-Expression

Using mise for Node.js:

Using mise for Node.js
# Install Node.js LTS
mise use node@lts
# Install specific version
# List installed versions
mise ls

mise can also auto-install default npm packages with each new Node.js version by configuring your ~/.config/mise/config.toml:

mise auto-install npm packages
[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:

Installing Volta via winget
winget install Volta.Volta

Volta automatically pins Node.js versions per project:

Using Volta
# Install Node.js
volta install node
# Pin a version for the current project

The Result: No More Permission Issues

After switching to mise, my Vite project creation works flawlessly:

Creating a Vite React project
npm create vite@latest my-react-app
cd my-react-app
npm install
npm run dev

No 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:

.node-version file
20.11.0

Or with .nvmrc format:

.nvmrc file
v18.19.0

When 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

  1. Not uninstalling existing Node.js first: nvm-windows specifically requires this. Having both installed causes PATH conflicts.

  2. 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.

  3. Forgetting to reinstall global packages: Each Node.js version has its own set of global packages. After switching versions, reinstall what you need.

  4. Not committing version files: Add .nvmrc or .node-version to your repository so team members use the same Node.js version.

  5. 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:

Oh, and if you found these resources useful, don’t forget to support me by starring the repo on GitHub!

Comments