
💭 Introduction
Today, for no apparent reason—or at least that’s what it seemed to me—I stumbled upon a problem that completely broke my build. It started with what looked like a typical npm install, but suddenly nothing worked anymore.
If you’ve ever faced cryptic errors like:
Cannot find module @rollup/rollup-win32-x64-msvc
Cannot find module @esbuild/win32-x64
…then you already know the pain. 😩
In this post, I’ll walk you through what happened, why this issue keeps coming back, what the real cause is, and—finally—how to fix it once and for all. Hopefully, this will save you from hours of frustration and help your team avoid the same trap.
🔍 The Problem: npm Optional Dependencies Gone Wrong
It all started in an Angular 18 project on Windows. Running npm install looked fine—until I tried to build:
npm run build
And suddenly:
✘ [ERROR] Cannot find module @rollup/rollup-win32-x64-msvc
After digging deeper, I discovered this was a known npm bug on Windows that affects optional dependencies—those platform-specific packages like @esbuild/win32-x64 or @rollup/rollup-win32-x64-msvc.
The issue: npm sometimes fails to install them properly depending on your cache, Node.js version, or even network timing.
You end up with Linux binaries on Windows, which obviously don’t run. 🙃
⚠️ It Never Really Goes Away…
You fix it. You reinstall. You clear caches. You even think it’s over… and then it comes back.
Sometimes on a different machine. Sometimes in a new project. Sometimes weeks later after a package update.
That’s when I realized—this wasn’t a one-off. This was part of a larger pattern of npm’s handling of optional dependencies across platforms.
To prove it, here’s the list of official issues still open (and some already closed) across the npm/cli and rollup/rollup repositories.
🗂️ The Landscape: npm & Rollup Issues (2022–2025)
🧱 npm/cli Issues
✅ Closed / Completed
- #4828 – Platform-specific optional dependencies not included in package-lock.json
- Fixed via PR #8184 (merged)
- Root cause of platform-dependent binary errors
- #7900 – npm install hangs for ~2 minutes with optional dependencies in npm 10.9.0
- Closed (November 2024)
- Performance fix
- #7868 – npm 10.9.0 stuck in WSL Ubuntu environment
- Fixed; Windows-specific
- #8260 – Error with npm install after creating Vite project
- Closed (not reproducible)
- #7961 – Optional deps for OS/CPU variants pruned unexpectedly
- Closed
- #7404 – Workspaces don’t honor shallow install strategy
- Closed
- #7395 – Certificate issue with GitHub-hosted package on Windows
- Closed (April 2024)
🔓 Open
- #8514 – libc field missing in package-lock.json
- Open since August 2025
- Affects native binary resolution (Linux)
- #7355 – Failed optional dependency builds block global installs
- Open since April 2024
🧮 Plus ~50 other issues mentioning “optional dependencies” in npm/cli still open.
🎛️ rollup/rollup Issues
🔓 Open
- #5901 – Cannot find module @rollup/rollup-win32-x64-msvc
- #5897 – Same error as above
- #5821 – Windows Security flags rollup.win32-x64-msvc.node as malware
- #5571 – Cannot find module @rollup/rollup-win32-x64-msvc (Rollup 4.18.1) ← 🏆 The most useful one
- #5295 – Unsupported platform
✅ Closed
- Closed January 2024
💡 The Turning Point: «Eureka!»
After reading through all those reports, I realized something:
the issue wasn’t always npm’s fault.
Sometimes, npm was simply doing what I told it to—unintentionally.
That’s when I found the hidden culprit: the npm config os setting.
🧩 Before You Blame npm: Check Your Configuration
Before diving into complex fixes or postinstall scripts, check this first.
Run this:
npm config get os
✅ Expected on Windows:
null(auto-detects your OS)win32
❌ Problem output on Windows:
linuxdarwin
If npm thinks your OS is Linux, it will install Linux binaries—even on Windows! 🤯
This happens often if:
- You used WSL and ran
npm config set os linux - You copied a
.npmrcfile from another machine - You work across Docker + Windows environments
- You’re using an old npm version
🛠️ The Fix
npm config delete os
npm config get os
# should return null
Then reinstall everything:
rm -rf node_modules package-lock.json
npm install
You’ll now get the correct win32-x64 binaries for Rollup, Esbuild, and Nx.
✅ Recommended npm version: 10.9.4 or higher
Upgrade if needed:
npm install -g npm@10
⚙️ The Root Cause (for Real This Time)
Once I fixed the OS config, npm finally did its job.
But understanding why this happens helps avoid it altogether.
In short:
npmskips installing optional dependencies when it thinks they’re for another platform.- If your
npm config ossayslinux, it won’t fetch Windows binaries. - Even reinstalling or clearing cache won’t help until that config is corrected.
🚀 Permanent Fixes and Best Practices
✅ Use lifecycle scripts wisely
Add preinstall/postinstall hooks to handle platform-specific installs automatically.
✅ Lock Node.js version via .nvmrc
echo "18.20.0" > .nvmrc
✅ Don’t commit .npmrc with OS-specific settings
.npmrc
✅ Use Yarn if all else fails
Yarn doesn’t have this optional-deps bug on Windows.
🎯 Conclusion
So, what started as “just another npm bug” turned out to be an invisible config problem hiding in plain sight.
The good news?
Once you know about it, fixing it takes less than a minute.
✅ Delete the wrong os config
✅ Use npm 10.9.4+
✅ Reinstall clean
✅ Enjoy working builds again
And maybe, just maybe, you’ll save someone else from losing half a day to this same issue. 😅
💬 If I’m being completely honest, I think what actually triggered the whole mess was my failed attempt to install NVM inside WSL2. I don’t remember exactly how I did it, but I’m convinced that was the spark that caused everything to go wrong! 🔥
If you ever plan to install NVM inside WSL2, make sure it has its own isolated setup and does not share paths or environment variables with your Windows installation.
Here’s how to clean up and reconfigure it properly:
# --- Clean Windows NVM paths from PATH (sample and optional) ---
export PATH=$(echo "$PATH" | tr ':' '\n' \
| grep -v '^/mnt/c/ProgramData/nvm' \
| grep -v '^/mnt/c/ProgramData/nvm/nodejs' \
| tr '\n' ':')
# --- Install NVM ---
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/master/install.sh | bash
# 🧩 Set up NVM for WSL2
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
Doing this ensures your WSL2 environment stays clean, isolated, and free from weird cross-path issues between Windows and Linux. 🚀
📚 References
- npm CLI Issue #4828 – Optional dependencies bug on Windows
- Rollup Issue #5571 – Missing Windows binary
- npm config documentation
- Angular 18 Documentation – Getting Started
- esbuild Documentation – Installation
- Node.js LTS Release Schedule
- Vite Documentation
✅ Key Takeaways
- Always check
npm config get osbefore assuming a bug - Don’t trust “fixes” that don’t explain the why
- Document what you learn — the next dev will thank you 🙌