The error, verbatim
Jump to the fix ↓Error: Cannot find native binding. 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 file:///C:/project/node_modules/rolldown/dist/shared/binding-DPuPeV1X.mjs:603:34
cause: Error: Cannot find module './rolldown-binding.win32-x64-msvc.node'
cause: Error: Cannot find module '@rolldown/binding-win32-x64-msvc'
cause: Error: Cannot find module './rolldown-binding.wasi.cjs'
cause: Error: Cannot find module '@rolldown/binding-wasm32-wasi'
# the same project folder, built inside WSL:
cause: Error: Cannot find module '@rolldown/binding-linux-x64-gnu'
cause: Error: Cannot find module '../rolldown-binding.linux-x64-gnu.node'
Tested on
- Vite
- 8.3.0 (Rolldown 1.2.10)
- npm
- 11.9.0
- Node
- 24.14.0
- OS
- Windows 11 Pro
- WSL
- Ubuntu 24.04, Node 24.21.0
Contents
Vite 8 builds with Rolldown, which is written in Rust and ships as a separate compiled file for each operating system. This error means the file for your system isn’t in node_modules. The platform in the message changes (win32-x64-msvc, linux-x64-gnu, linux-x64-musl, darwin-arm64…), but the causes and the fix are the same everywhere.
The fix
In most cases, a plain install puts the missing file back. You don’t need to delete anything first:
npm iIf the error comes straight back after that, npm has been told to skip optional packages. Check:
npm config get omitIf it prints optional, that’s the cause. Remove omit=optional from the .npmrc it came from (the project’s, or your user-level one), then run npm i again.
What actually causes it
The error message blames an npm bug. In my tests, the missing file had two ordinary causes, and neither was that bug:
1. Optional packages were skipped
Rolldown lists its per-platform files as optional dependencies, so npm installs only the one matching your machine. Anything that tells npm to skip optional packages removes it:
npm install --omit=optionalomit=optionalin.npmrc
After npm i --omit=optional, the @rolldown folder held pluginutils and nothing else, and the build failed with exactly the error above.
2. node_modules came from another operating system
node_modules is not portable between operating systems. I installed the project as if on Linux, then ran it on Windows:
node_modules/@rolldown/binding-linux-x64-gnu <- present
node_modules/@rolldown/binding-win32-x64-msvc <- missing
Same error. This is what happens when node_modules is copied from WSL, a Docker container, a Mac, or a teammate’s machine, or when a Docker bind mount shares the host’s node_modules with a container.
Windows and WSL sharing one project folder
This is the most common way to meet the Linux version of the error. You install on Windows, then open the same folder in WSL (under /mnt/c/…) and build there:
cause: Error: Cannot find module '@rolldown/binding-linux-x64-gnu'
cause: Error: Cannot find module '../rolldown-binding.linux-x64-gnu.node'
The Windows install only fetched the Windows binding. WSL runs Linux, so it looks for the Linux one.
Best: one install per system. Keep a separate copy of the project inside WSL’s own filesystem (for example ~/my-app, not /mnt/c/...) and run npm i there. It gets the Linux binding, and your Windows folder keeps the Windows one.
If you really need one folder for both, add the other system’s binding yourself, at exactly the Rolldown version you have. Check the version first:
npm ls rolldownThen, on Windows, with that version (1.2.11 in my test):
npm i -D @rolldown/binding-linux-x64-gnu@1.2.11 --forceAbout the npm bug the message mentions
The message points to npm/cli#4828, a long-standing issue where a lockfile created on one platform could leave out other platforms’ optional packages. I tried to trigger it: I created package-lock.json for Linux, deleted node_modules, and ran npm ci on Windows.
On npm 11.9.0 it installed the correct Windows binding and the build passed. So on current npm, the lockfile alone didn’t cause this. That’s why deleting package-lock.json, as the message suggests, is usually more than you need: it works, but it also unpins every dependency version in your project.
The binding name for your system
The message names the package for the machine it ran on. These are the ones Rolldown 1.2.10 ships:
| System | Package |
|---|---|
| Windows x64 | @rolldown/binding-win32-x64-msvc |
| Windows ARM | @rolldown/binding-win32-arm64-msvc |
| macOS Apple Silicon | @rolldown/binding-darwin-arm64 |
| macOS Intel | @rolldown/binding-darwin-x64 |
| Linux x64 (Ubuntu, Debian…) | @rolldown/binding-linux-x64-gnu |
| Linux x64, Alpine (Docker) | @rolldown/binding-linux-x64-musl |
| Linux ARM64 | @rolldown/binding-linux-arm64-gnu / -musl |
The gnu and musl pair matters in Docker: Alpine images use musl, most other Linux systems use gnu, so a node_modules built on one won’t have the file the other looks for.
What didn’t work
How this was tested
A fresh Vite 8.3.0 project (Rolldown 1.2.10) on Windows 11 with Node 24.14.0 and npm 11.9.0. The binding was removed three ways: --omit=optional, a Linux-targeted install (--os=linux --cpu=x64 --libc=glibc) run on Windows, and omit=optional in a project .npmrc. The fixes were then run against those broken states, and npm ci was tried with a Linux-made lockfile. The Windows and WSL section was tested on September 29 with Vite 8.3.1 (Rolldown 1.2.11): installed from Windows, then built in WSL Ubuntu 24.04 with its own Linux Node 24.21.0, in the same folder and in a separate copy in the WSL home. Every error and every result above is the real output.
— N.K., end of entry No.019