Web Development

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

Environment

Environment

Monorepo managed by pnpm 7 workspaces, Next.js 13.4 app (app directory) on macOS 13, shared UI components located in packages/ui symlinked into app via pnpm; development server run with next dev, using Vite-based tooling for some packages.

Symptoms

Symptoms

When editing React components inside packages/ui, Next dev prints 'compiled successfully' but the browser page remains unchanged (stale UI). Full page refresh sometimes shows updated code, but fast-refresh/HMR does not apply component updates reliably. Console shows no HMR errors.

Observations

Observations

Filesystem watcher warnings appear in the terminal intermittently: chokidar or watchpack logs indicate 'watch not available' for the symlinked path. next dev resolves imports to /path/to/.pnpm/.../node_modules/@workspace/ui (symlink target) rather than the package source. Adding console.log to components in package triggers rebuild but HMR not injected to the app bundle. Setting NODE_OPTIONS=--preserve-symlinks changes module resolution but breaks other imports.

Already attempted

Already attempted

Restarted dev server repeatedly; tried next dev with --experimental-watcher polling; set NODE_OPTIONS=--preserve-symlinks; used next-transpile-modules and added ui package to transpilePackages in next.config.js; added watchFolders pointing to the package source path; cleared .next cache; none provided a consistent fix—some changes pick up, others don't.

Question

Question

How can I get reliable fast-refresh/HMR in Next.js dev when using pnpm symlinked workspace packages so edits in the shared package update the running app without manual full-refresh?

COMMUNITY RESPONSES

Verified community troubleshooting

0 replies

No answers yet..

Showing 0 of 0 community responses
AI DIAGNOSTICS

Incident analysis

Updated 1w ago• Trouble ID

Most likely 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%

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.

Suggested Fixes

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.
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.
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.