FULL AI ANALYSIS

Next.js dev server HMR and fast-refresh fail for symlinked package in pnpm workspace (stale pages in browser)

Generated Oct 3, 2026, 12:35:03 AM

Analysis summary

Next.js’ dev server and underlying webpack/chokidar file-watching can miss changes in symlinked packages because by default Next ignores node_modules and resolves symlinks to the package's installed location, not the workspace source. Tools like pnpm create symlink/virtual store layouts that confuse watchers. Solutions typically involve telling Next to include the package source in watchFolders and to transpile it (so it's treated as application code), and ensuring the file watcher supports watching symlinked directories (polling or correct chokidar options). preserve-symlinks changes module resolution semantics and can introduce duplicate React copies or break hooks, so it’s a risky global option.

Possible causes

Next.js excludes node_modules from HMR and resolves symlinked workspace packages to node_modules virtual store, causing changes in source not to be watched.

90%

File watcher (chokidar/watchpack) does not follow symlinks by default on this platform or is limited by FS events; symlinked paths are not in Next's watchFolders.

85%

Package is not being transpiled by Next (JS/TS in node_modules) so HMR update pipeline is not invoked.

60%

Multiple React copies due to preserve-symlinks leading to inconsistent HMR behavior.

25%

Suggested fixes

1

Diagnostic step 1

Add the workspace package source to Next's watchFolders and transpile list in next.config.js: - transpilePackages: ['@your-org/ui'] - webpack-dev middleware: include the path via watchFolders: [path.resolve(__dirname, '../packages/ui')] This tells Next to treat the package as application code and watch its files.

2

Diagnostic step 2

Use Next.js' built-in transpilePackages (Next 12.2+/13+): add packages to next.config.js so files get processed by Next's compiler and HMR can propagate updates.

3

Diagnostic step 3

If file events are unreliable, enable polling for the watcher during dev (set CHOKIDAR_USEPOLLING=true or use watchOptions.poll) as a test; polling is heavier but works across symlink/FS event edge cases.

4

Diagnostic step 4

Avoid using NODE_OPTIONS=--preserve-symlinks unless you understand implications; if used, ensure single React instance by resolving aliases and avoiding duplicate installs.

5

Diagnostic step 5

If problems persist after these settings, collect diagnostics: run the dev server with DEBUG=next:* and capture logs of module resolution and watcher events. Provide those logs and a minimal reproduction repo to Next.js maintainers or pnpm workspace repo for deeper debugging—this may require an upstream fix in watchpack/chokidar. For CI or production builds, ensure you build from source copies (not symlinked node_modules) to avoid runtime surprises.