Skip to content

React Compiler + Turbopack: browser source map sourcesContent is the compiler output (wrong line numbers) for client→client imports #94450

@atkaiser

Description

@atkaiser

Link to the code that reproduces this issue

https://github.com/atkaiser/rc-sourcemap-repro

To Reproduce

  1. Clone the reproduction and install deps:

    git clone https://github.com/atkaiser/rc-sourcemap-repro
    cd rc-sourcemap-repro
    npm install

    The repo is two files: app/page.tsx ('use client') imports app/widget.tsx
    ('use client', a single useState). next.config.mjs sets
    reactCompiler: true and productionBrowserSourceMaps: true.

  2. Build with the React Compiler enabled (the default):

    npm run build
  3. Inspect the generated browser source map:

    npm run inspect

    This finds the .next/static/chunks/*.js.map whose sources includes
    app/widget.tsx and prints its sourcesContent. Observe 27 lines
    containing import { c as _c } from "react/compiler-runtime"
    VERDICT: BUG. (Manual equivalent: open the chunk .js.map, find the entry
    whose sources contains app/widget.tsx, read sourcesContent.)

  4. Rebuild with the compiler disabled:

    npm run build:no-rc   # = reactCompiler:false via REACT_COMPILER=false next build
  5. Inspect again:

    npm run inspect

    Now sourcesContent is 9 lines — identical to the real file
    VERDICT: OK.

Current vs. Expected behavior

Current (reactCompiler: true): the browser source map for
app/widget.tsx has its sourcesContent set to the React Compiler output
(27 lines, beginning import { c as _c } from "react/compiler-runtime" plus a
generated cache and hoisted helpers) instead of the 9-line source file. Resolved
stack-frame line numbers therefore point past the end of the real file,
breaking devtools "original source" view and the line-accurate "open in
repository" links that error trackers (Datadog / Sentry) generate from the map.

Expected: sourcesContent should be the original app/widget.tsx, with line
numbers mapping back to the real source — exactly what happens with
reactCompiler: false.

reactCompiler app/widget.tsx sourcesContent line numbers
true 27 lines (compiler output, c as _c) wrong
false 9 lines (= the real file) correct

This is not "expected React Compiler behavior" — it is inconsistent.
With reactCompiler: true, a standalone 'use client' page, and a 'use client'
component imported by a server component, both map correctly back to source.
Only a client component imported by another client component breaks. So the
pipeline is able to chain the compiler's map back to the original source; it just
fails on the client→client path.

Provide environment information

Operating System:
  Platform: darwin
  Arch: arm64
  Version: Darwin Kernel Version 25.2.0: Tue Nov 18 21:09:56 PST 2025; root:xnu-12377.61.12~1/RELEASE_ARM64_T6041
  Available memory (MB): 24576
  Available CPU cores: 14
Binaries:
  Node: 22.14.0
  npm: 10.9.2
  Yarn: 1.22.22
  pnpm: N/A
Relevant Packages:
  next: 16.3.0-canary.40 // Latest available version is detected (16.3.0-canary.40).
  eslint-config-next: N/A
  react: 19.2.6
  react-dom: 19.2.6
  typescript: 5.7.3
Next.js Config:
  output: N/A

Tested and reproduces on **`next@16.3.0-canary.40`** (per the "test on canary" guidance) as well as `next@16.2.6` stable.

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

Turbopack, Output

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

next build (local)

Additional context

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    OutputRelated to the the output configuration option.TurbopackRelated to Turbopack with Next.js.

    Type

    No fields configured for Bug.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions