Skip to content

[Turbopack] Infinite Suspense remount cycle with React.lazy() + 15+ useSyncExternalStore selectors #92372

@mmmprod

Description

@mmmprod

Link to the code that reproduces this issue

https://github.com/mmmprod/turbopack-suspense-remount-repro

To Reproduce

  1. Clone the repo: git clone https://github.com/mmmprod/turbopack-suspense-remount-repro
  2. npm install
  3. npm run dev (Turbopack, default in Next.js 16)
  4. Open http://localhost:3000 in browser
  5. Open browser console (F12)
  6. Observe [HeavyComponent] render mount=XXXX logs — each pair has a different mount ID, meaning the component is unmounted and remounted infinitely

Current vs. Expected Behavior

Current: The lazy-loaded component enters an infinite unmount/remount cycle. Each mount gets a new React instance (different useRef value). The page never becomes interactive.

Expected: The component should mount once (+ StrictMode double), render, and stay mounted.

Only affects Turbopack dev mode

Mode Result
next dev (Turbopack) Infinite remount loop
next dev --webpack Works perfectly
next build && next start Works perfectly

Environment

  • Next.js: 16.2.2
  • React: 19.2.4
  • Node.js: 20.20.0
  • OS: Linux (WSL2)

Component characteristics

The reproduction component has 15+ Zustand useSyncExternalStore selectors across 3 stores, useContext consumer, 4 useMemo, 3 useCallback, 2 useEffect. Loaded via React.lazy() inside Suspense.

Simpler components with 2-3 selectors do NOT reproduce.

Workaround

Eager-import the component in dev, lazy in prod:

import { HeavyComponent as Eager } from "./HeavyComponent";
const HeavyComponent = process.env.NODE_ENV === "production"
  ? lazy(() => import("./HeavyComponent").then(m => ({ default: m.HeavyComponent })))
  : Eager;

Which area(s) are affected?

Turbopack

Which stage(s) are affected?

next dev (Development)

Metadata

Metadata

Assignees

No one assigned

    Labels

    TurbopackRelated to Turbopack with Next.js.linear: turbopackConfirmed issue that is tracked by the Turbopack team.

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions