Skip to content

Turbopack + optimizePackageImports tree-shakes a sideEffects-allowlisted, side-effect-only module (breaks react-focus-lock) #96333

Description

@sentience

Link to the code that reproduces this issue

https://github.com/cultureamp/turbopack-sidecar-treeshaking-repro

To Reproduce

  1. npm install
  2. npm run build – ❌ Turbopack (Next's default bundler) — build FAILS at prerender: "Error: Sidecar medium not found"
  3. npm run build:webpack – ✅ webpack — same config, builds fine

Current vs. Expected behavior

With experimental.optimizePackageImports containing both react-focus-on and react-focus-lock, a production Turbopack build tree-shakes react-focus-lock's side-effect-only sidecar module out of the bundle. That module's sole purpose is a registration side-effect (exportSidecar(mediumSidecar, FocusTrap)); with it gone, rendering any focus trap throws:

Error: Sidecar medium not found

react-focus-lock's package.json marks the module side-effectful via a sideEffects allowlist (["**/sidecar.js", "**/index.js"]), so it should be retained. webpack retains it; Turbopack drops it when the import is rewritten by optimizePackageImports.

Expected

optimizePackageImports should not cause a module in the target package's sideEffects allowlist to be dropped. Turbopack should honour sideEffects for side-effect-only (bare) imports even when the barrel import is rewritten by the optimization.

Provide environment information

Operating System:
  Platform: darwin
  Arch: arm64
  Version: Darwin Kernel Version 25.5.0: Tue Jun  9 22:28:34 PDT 2026; root:xnu-12377.121.10~1/RELEASE_ARM64_T6041
  Available memory (MB): 49152
  Available CPU cores: 14
Binaries:
  Node: 26.5.0
  npm: 11.17.0
  Yarn: N/A
  pnpm: 10.34.5
Relevant Packages:
  next: 16.3.0-canary.102 // Latest available version is detected (16.3.0-canary.102).
  eslint-config-next: N/A
  react: 19.2.8
  react-dom: 19.2.8
  typescript: N/A
Next.js Config:
  output: N/A


Note: Above-linked repro repo is on Next 16.2.11, but I've verified it still reproduces with the current canary.

Which area(s) are affected? (Select all that apply)

Turbopack

Which stage(s) are affected? (Select all that apply)

next build (local)

Additional context

  • Reproduces only in a production Turbopack build; next dev, next build --webpack, unit tests, and Storybook all pass — so it typically surfaces only in deployed apps.
  • Impact is broad: optimizePackageImports is widely used (Next enables it by default for many packages; design systems add their own), and most modal/popover/menu components transitively use react-focus-on / react-focus-lock.
  • react-remove-scroll uses the same sidecar pattern and is likely affected the same way.

Metadata

Metadata

Assignees

No one assigned

    Labels

    TurbopackRelated to Turbopack with Next.js.

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions