Cannot find module 'react' in Docker runner: use-sync-external-store/shim leaves __require('react') unresolved in SSR chunk
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 11.2k
- Forks
- 899
- Avg merge
- 2d 24m
- Merged PRs (30d)
- 40
Description
Bug Report
When using Nitro (via TanStack Start) in a pnpm monorepo with @auth0/auth0-react and a workspace package that uses use-sync-external-store/shim, the built SSR bundle contains an unresolved __require("react") call. This fails at runtime in any Docker runner stage where node_modules is not present.
Reproduction
https://github.com/psachs-alto/nitro-rolldown-repro
git clone https://github.com/psachs-alto/nitro-rolldown-repro
cd nitro-rolldown-repro
docker build -t repro .
docker run -p 3000:3000 repro
curl http://localhost:3000/
Error
Error: Cannot find module 'react'
Require stack:
- /app/.output/server/_ssr/app-<hash>.mjs
at Module._resolveFilename (node:internal/modules/cjs/loader:1456:15)
...
code: 'MODULE_NOT_FOUND',
requireStack: [ '/app/.output/server/_ssr/app-<hash>.mjs' ]
Root Cause
Rolldown splits the SSR bundle into multiple chunks. When @auth0/auth0-react is present, Auth0 + React are bundled together into _libs/auth0__auth0-react+react.mjs, which exports an inlined require_react. However, use-sync-external-store/shim (coming from a separate workspace package) ends up in a different SSR chunk (_ssr/app-*.mjs) that does not have access to the inlined React. Instead it contains:
var require_use_sync_external_store_shim_production = /* @__PURE__ */ __commonJSMin(((exports) => {
var React = __require("react"); // __require = createRequire(import.meta.url)
...
}));
__require is createRequire(import.meta.url) — a real Node.js require(). The Nitro runner stage only copies .output/ (not node_modules), so require("react") has nothing to resolve and throws.
Note: nf3 already handles this for tslib by copying it into .output/server/node_modules. react needs the same treatment when it appears as an implicit CJS external in @__PURE__ factory wrappers.
Workaround
After pnpm run build, copy React into the server output:
node -e "
const fs = require('fs'), path = require('path');
const r = path.dirname(require.resolve('react/package.json'));
fs.cpSync(r, '.output/server/node_modules/react', { recursive: true, dereference: true });
"
Environment
| nitro | 3.0.1-alpha.2 |
| react | 19.2.3 |
| @tanstack/react-start | 1.167.9 |
| @auth0/auth0-react | ^2.16.0 |
| use-sync-external-store | ^1.5.0 |
| vite (Rolldown) | ^8.0.3 |
| pnpm | 10.28.0 |
| Node.js | 24 |
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Clone the linked nitro-rolldown-repro repository and run its Docker build, then inspect the generated .output/server SSR chunks and node_modules handling. Start from the unresolved __require("react") in the SSR chunk and compare it with the existing tslib treatment. Done means the Docker runner starts and curl http://localhost:3000/ succeeds without node_modules outside .output.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- docker, node.js, react, typescript, vite
- Domain
- backend, build-system, devops
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100