TypeScript

Fix Cannot find module @rollup/rollup-win32-x64-msvc

Find out where your node_modules came from, reinstall it for the machine that runs Vite, and avoid the popular fix that breaks Linux CI and Docker builds.

Mahdi Ben RhoumaMahdi Ben Rhouma
Updated
8 min read

TL;DR#

Rollup 4, which Vite 5 to 7 build with, loads a native binary published as a separate npm package per platform: @rollup/rollup-win32-x64-msvc on 64-bit Windows, @rollup/rollup-linux-x64-gnu on most Linux machines, and so on. npm installs only the packages whose os and cpu match the machine running the install. If the node_modules folder on your Windows machine was installed somewhere else (WSL, a Linux container, a colleague's Mac, a synced folder), the Windows binary is not there and Vite stops before it starts. Delete node_modules and run npm ci on the Windows machine itself. Do not "fix" it by adding the Windows package as a dependency: that breaks every Linux install of the project. If the native binary now loads but Vite stops with crypto.hash is not a function, check the Node runtime that actually launches Vite rather than reinstalling the platform package again.

The question on Stack Overflow comes from a fresh Vite project that fails on npm run dev. The same error was reproduced on 4 October on Windows 11 with Vite 7.3.6, by installing node_modules for Linux and then running the build on Windows:

text
Error: Cannot find module @rollup/rollup-win32-x64-msvc. npm has a bug related to optional dependencies (https://github.com/npm/cli/issues/4828). Please try `npm i` again after removing both package-lock.json and node_modules directory.
    at requireWithFriendlyError (C:\Users\mahdi\AppData\Local\Temp\claude\rolluprepro\node_modules\rollup\dist\native.js:121:9)
  [cause]: Error: Cannot find module '@rollup/rollup-win32-x64-msvc'

Why the Windows binary is missing#

Rollup's parser is native code. Instead of compiling it on your machine, Rollup lists one prebuilt package per platform as an optional dependency, and each of those packages declares the os and cpu it runs on. When npm installs the project, it keeps only the optional packages whose os and cpu match the current machine and skips the others. The npm package.json documentation describes the os and cpu fields that drive this.

At start-up, rollup/dist/native.js works out the current platform and requires the matching package. The stack trace points to that file. If the package is not in node_modules, Rollup throws the error above.

So the binary goes missing whenever the folder that was installed on one platform is used on another. In the reproduction, the only Rollup binary present was the Linux one:

text
$ ls node_modules/@rollup
rollup-linux-x64-gnu

Common ways to end up there:

  1. npm install ran in WSL or a dev container, and the project is then run from Windows on the same folder.
  2. A Dockerfile or a CI cache copied node_modules from a Linux stage into a Windows job, or the other way round.
  3. The project folder, node_modules included, was zipped, synced through a cloud drive, or committed to git by mistake.

The text "npm has a bug related to optional dependencies" refers to npm/cli#4828. In that bug, running npm install with an existing node_modules could leave other platforms' optional packages out of package-lock.json. The issue was closed by PR #8184 in April 2025. Comparing tags on GitHub shows that its merge commit is in npm v11.3.0 and not in v11.2.0. The node:22 Docker image still ships npm 10.9.9, which does not contain that commit.

Fix#

1. Check whether the lockfile is fine#

In most projects the lockfile is not the problem. Search it for the Windows entry:

bash
grep -c '"node_modules/@rollup/rollup-win32-x64-msvc"' package-lock.json

On Windows without Git Bash, use PowerShell:

powershell
Select-String -Path package-lock.json -Pattern 'node_modules/@rollup/rollup-win32-x64-msvc' | Measure-Object

A count of 1 means the lockfile already lists the Windows binary. In the reproduction, this exact command printed 1 on a lockfile written by an install for Linux:

text
1

2. Reinstall node_modules on the machine that runs Vite#

bash
rm -rf node_modules
npm ci

In PowerShell, use Remove-Item -Recurse -Force node_modules, then npm ci. Run it from the same environment that runs npm run dev: a Windows terminal for a Windows Vite, the WSL shell for a WSL Vite. In the reproduction, npm ci on Windows installed the Windows binaries and the build passed:

text
added 14 packages in 2s
rollup-win32-x64-gnu
rollup-win32-x64-msvc

With npm 11.19, a plain npm install over the Linux-installed folder also repaired it. It removed the Linux binary and added the Windows ones:

text
added 3 packages, and removed 3 packages in 460ms

3. Only if the lockfile lacks the entry: regenerate it#

If step 1 printed 0, the lockfile was written by an npm affected by #4828. Do what the error message suggests, once, and commit the result:

bash
rm -rf node_modules package-lock.json
npm install

Then repeat step 1 and confirm that the Windows entry is in the new lockfile before you commit it.

4. Stop node_modules from crossing machines#

Each platform should run its own install. In Docker, list node_modules in .dockerignore and run npm ci inside the image. In CI, include the operating system in the cache key, or cache npm's download cache instead of node_modules. Keep node_modules in .gitignore. The same rule applies to every package that ships per-platform native code. The node-sass binding error is the same mistake with another package: a binary built for one OS and Node version, used on another.

The most voted answer on the Stack Overflow question is npm install @rollup/rollup-win32-x64-msvc. It does make the Windows machine work, but look at what it writes into package.json:

text
{"name":"rollup-repro","private":true,"version":"1.0.0","type":"module","scripts":{"dev":"vite","build":"vite build"},"devDependencies":{"vite":"7.3.6"},"dependencies":{"@rollup/rollup-win32-x64-msvc":"^4.64.0"}}

The Windows binary becomes a regular dependency instead of an optional one. In the reproduction, the same project installed with npm ci in the official node:22 image, which runs Linux, failed immediately:

text
npm error code EBADPLATFORM
npm error notsup Unsupported platform for @rollup/rollup-win32-x64-msvc@4.64.0: wanted {"os":"win32","cpu":"x64"} (current: {"os":"linux","cpu":"x64"})

That is every Linux CI runner, every Docker build and every Linux or macOS colleague. If you already added it, remove it with npm uninstall @rollup/rollup-win32-x64-msvc and apply step 2.

Two other answers suggest installing an older Vite 4 release or running npm update. Vite 4 avoids the error for a different reason: it depends on Rollup 3, whose parser is pure JavaScript, so there is no @rollup/rollup-<platform> package to go missing. Downgrading Vite three majors to dodge an install problem is not the fix. npm update helps because it runs the install again for the current machine, which adds the missing binary without deleting node_modules; on an old lockfile it can also move Rollup past the DLL problem described below.

Verify the fix#

bash
ls node_modules/@rollup
npm run build

On 64-bit Windows the listing should contain rollup-win32-x64-msvc. The build should end with a line like built in 169ms. Run the same two commands in your Linux CI or Docker build, and the listing should show the Linux package instead. That proves each platform installed its own binary and package.json does not force one. If the listing does show rollup-win32-x64-msvc and the build still stops with the same message, read the [cause] at the end of the stack trace: "The specified module could not be found" with ERR_DLOPEN_FAILED means Windows found the binary but cannot load a DLL it depends on, which the ERR_DLOPEN_FAILED fix solves by updating Rollup or installing the Visual C++ Redistributable.

One email a month — the latest explained errors

What the site published that month — mostly Next.js, Supabase and Node errors, explained. You confirm by email; unsubscribe any time in one click.

When the module name is different#

The error names the package for the platform that is running. @rollup/rollup-linux-x64-gnu in a Docker build means a Windows or macOS node_modules was copied into a Linux image. @rollup/rollup-linux-x64-musl means an Alpine image. The fix is the same in each case: install inside the environment that runs the build, as in step 4. On Vite 8 you will not see a Rollup module at all, because vite@8.3.2 depends on rolldown instead of rollup. Rolldown also publishes native binaries per platform, so a copied node_modules fails there for the same reason.

Once Vite starts, the next build error usually comes from your own files. If it now reports that Rollup "failed to resolve import" for your entry file, the Vite entry resolution fix covers an index.html placed inside src together with a custom root. If the build runs in Docker and stops at a missing compiler binary such as tsc, see tsc not found in Docker.

The message tells you to delete everything and reinstall. Most of the time, deleting only node_modules and running npm ci on the right machine is enough, and adding the binary by hand is the one thing to avoid.

Further reading: Fix: No loader is configured for ".node" files (Vite), Fix tsc is not recognized: run the local compiler. Also see Fix Vite "Cannot find package vite" in vite.config.ts. Also see Failed to parse source map: fix the missing src warning.

Frequently Asked Questions

|

Have more questions? Contact us

Still stuck? Paste your error.

Paste the error message or stack trace — we check it against every fix and tool on the site.

Matching happens in your browser. When you search, a cleaned error signature is sent so we can spot errors we do not cover yet — never the raw text, your IP address or your e-mail. Do not paste passwords or keys. Details

Written by

Mahdi Ben Rhouma
Mahdi Ben Rhouma

Full-Stack Dev — Next.js & Supabase

Solo developer building SaaS products with Next.js and Supabase. Writing about production patterns the official docs skip.

Remote