nextjs - ✅(Solved) Fix @next/mdx: Turbopack rule uses `as: '*.tsx'` causing unnecessary double-processing of MDX output [1 pull requests, 4 comments, 2 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
vercel/next.js#91103Fetched 2026-04-08 00:18:59
View on GitHub
Comments
4
Participants
2
Timeline
6
Reactions
0
Timeline (top)
commented ×3cross-referenced ×1issue_type_added ×1labeled ×1

Fix Action

Fixed

PR fix notes

PR #91134: fix(mdx): use as: '.js' instead of '.tsx' in Turbopack rule

Description (problem / solution / changelog)

Fixes #91103

Problem

The Turbopack loader rule for .mdx files sets as: '*.tsx', which routes already-compiled JavaScript through Turbopack's full TypeScript/JSX pipeline a second time.

@mdx-js/mdx already compiles MDX to plain JavaScript using the automatic JSX runtime (_jsx()/_jsxs() calls). The output contains no JSX syntax and no TypeScript, so the extra pipeline is pure overhead.

For large MDX files (e.g., rehype-katex on a math-heavy page: ~1.9 MB), the redundant source-map merging alone adds ~50 s of compilation time.

Fix

Change as: '*.tsx'as: '*.js' so Turbopack treats the loader output as plain JavaScript and skips the unnecessary TypeScript/JSX pipeline.

Changed files

  • packages/next-mdx/index.js (modified, +1/-1)

Code Example

Operating System:
  Platform: linux
  Arch: x64
  Version: #1 SMP PREEMPT_DYNAMIC Sun Aug  6 20:05:33 UTC 2023
  Available memory (MB): 4102
  Available CPU cores: 2
Binaries:
  Node: 20.12.1
  npm: 10.5.0
  Yarn: 1.22.19
  pnpm: 8.15.6
Relevant Packages:
  next: 16.2.0-canary.85 // Latest available version is detected (16.2.0-canary.85).
  eslint-config-next: N/A
  react: 19.2.4
  react-dom: 19.2.4
  typescript: 5.9.3
RAW_BUFFERClick to expand / collapse

Link to the code that reproduces this issue

https://codesandbox.io/p/devbox/staging-monad-ns775c

To Reproduce

  1. Create a Next.js app with @next/mdx and Turbopack enabled (default in canary).
  2. Add a page like app/heavy/page.mdx that uses rehype-katex with several math equations.
  3. Run next dev.
  4. Observe that compilation of the MDX file takes significantly longer than expected.

The slow path is triggered by as: '*.tsx' in the Turbopack rule inside packages/next-mdx/index.js, which routes already-compiled JavaScript through Turbopack's TypeScript/JSX pipeline a second time.

Current vs. Expected behavior

Current: The Turbopack loader rule for .mdx files sets as: '*.tsx', which tells Turbopack to re-process the loader output through its full TypeScript/JSX pipeline (type-stripping → JSX transform → source-map merge). @mdx-js/mdx already compiles MDX to plain JavaScript using the automatic JSX runtime (_jsx()/_jsxs() calls). The output contains no JSX syntax and no TypeScript, so the extra pipeline is pure overhead. For large outputs (e.g. rehype-katex on a math-heavy page: ~1.9 MB), the redundant source-map merging alone adds ~50 s of compilation time.

Expected: The rule should use as: '*.js' so Turbopack treats the loader output as plain JavaScript and skips the unnecessary TypeScript/JSX pipeline. The fix is a one-line change:

- as: '*.tsx',
+ as: '*.js',

Provide environment information

Operating System:
  Platform: linux
  Arch: x64
  Version: #1 SMP PREEMPT_DYNAMIC Sun Aug  6 20:05:33 UTC 2023
  Available memory (MB): 4102
  Available CPU cores: 2
Binaries:
  Node: 20.12.1
  npm: 10.5.0
  Yarn: 1.22.19
  pnpm: 8.15.6
Relevant Packages:
  next: 16.2.0-canary.85 // Latest available version is detected (16.2.0-canary.85).
  eslint-config-next: N/A
  react: 19.2.4
  react-dom: 19.2.4
  typescript: 5.9.3

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

Markdown (MDX)

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

next dev (local)

Additional context

No response

extent analysis

Fix: Change the Turbopack rule for MDX output from *.tsx*.js

The MDX loader already emits plain JavaScript (no JSX/TS).
Telling Turbopack to treat the result as *.tsx forces an unnecessary TypeScript/JSX pass, which adds tens of seconds for large pages.

1️⃣ Edit the MDX plugin source

File: packages/next-mdx/index.js (or wherever the Turbopack rule is defined)

// … existing imports …

module.exports = {
  // …
  webpack(config, { dev, isServer }) {
    // other rules …

    config.module.rules.push({
      test: /\.mdx?$/,
      // The loader that turns MDX → JS
      use: [
        {
          loader: require.resolve('./mdx-loader'), // ← your custom loader
          options: {
            // … loader options …
          },
        },
      ],
-      // ❌ Old: forces a second TS/JSX pipeline
-      as: '*.tsx',
+      // ✅ New: treat the output as plain JavaScript
+      as: '*.js',
    });

    return config;
  },
};

If the rule lives in a separate next-mdx package, open that package’s index.js and apply the same diff.

2️⃣ Re‑install / rebuild

# From the repo root
pnpm install   # or npm/yarn
pnpm run build # optional – just to be sure the compiled assets are fresh

3️⃣ Run the dev server and measure

next dev
# Open the heavy MDX page and watch the terminal.
# Expected: compilation finishes in < 1 s (instead of ~50 s).

You can also time it:

time node_modules/.bin/next dev

4️⃣ Optional: Guard against future regressions

Add a comment next to the rule so future contributors know why *.js is required:

// MDX loader already outputs plain JS; using *.tsx would re‑run the TS/JSX pipeline
// and cause massive slow‑downs for large pages (e.g. rehype‑katex output).
as: '*.js',

5️⃣ Verify the

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING