nextjs - ✅(Solved) Fix Get information on the problem CSS in TURBOPACK [1 pull requests, 2 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#91423Fetched 2026-04-08 02:02:03
View on GitHub
Comments
2
Participants
2
Timeline
4
Reactions
2
Participants
Timeline (top)
commented ×2issue_type_added ×1labeled ×1

PR fix notes

PR #89615: Turbopack: fix a css order violation

Description (problem / solution / changelog)

What

Fix CSS cascade order violations in production builds when shared CSS chunks are emitted in the wrong position relative to non-shared chunks.

When a component imports and overrides styles from another component, the CSS cascade order could be violated in production builds. For example:

CardWrapper.module.css (sets background: purple)
  └── imports Card.module.css (sets background: white)

The expected behavior is that CardWrapper's purple background overrides Card's white background. However, in production builds, the shared chunk containing Card's CSS could be served before or after the wrong items, causing incorrect cascade order.

Why

The style chunking algorithm (style_groups.rs) groups CSS modules into shared batches to reduce HTTP requests. The chunk emission code (style_production.rs) must then emit these batches in the correct order relative to non-shared items.

The previous approach was incorrect, there we emitted the shared batch when the first of its members appeared in DFS post-order. This could emit the batch too early, before items that depend on later batch members. The alternate approach of 'emit on last member' also doesn't work, since we can emit the batch too late, after non-shared items that should have come after the batch.

The core issue is that DFS post-order is an over-specification: it produces a single linear ordering of all CSS modules, but a shared batch groups members whose positions may interleave with unrelated non-shared items. No fixed "emit at position X" strategy works, because the correct position depends on the actual dependency relationships between emission units (batches and individual items). Even dynamically detecting this doesn't work for the simple reason that we can batch modules in a way that will always violate a given routes order.

Concrete example

DFS post-order for an endpoint: [A, B, C, D, E] where {A, C} form a shared batch and B, D, E are non-shared.

  • If A must precede B in the cascade, the batch must come before B: [{A,C}, B, D, E]
  • Emit-on-first gives: [{A,C}, B, D, E] — correct by accident
  • Emit-on-last gives: [B, {A,C}, D, E]wrong, B loads before A

But in a different scenario where C depends on B:

  • Emit-on-first gives: [{A,C}, B, D, E]wrong, C loads before B

Neither heuristic is generally correct. The ordering must be computed from actual dependency edges.

How

style_groups.rs

  • FxIndexMap for chunk_group_indices: Changed from FxHashMap to FxIndexMap for deterministic iteration order. Since chunk groups are processed sequentially, insertion order equals sorted order. Non-deterministic iteration caused CSS ordering bugs (see #89523).
  • Collect dependents from all chunk groups: The previous approach found the shortest chunk group and only looked for dependents there (as an optimization). This was incorrect — it could miss dependents that only appear in other chunk groups. Now we union potential dependents from all chunk groups.
  • Use FxHashSet for dependents: Changed from Vec to FxHashSet for deduplication across multiple groups.
  • Contiguity check for batch candidates: When considering a candidate module for a shared batch, verify that in every route containing both the candidate and existing batch members, no unprocessed non-batch module exists in the gap between them. Without this, the batching algorithm could group modules that are non-contiguous in some routes' orderings (e.g. shared1 and shared2 when a route-unique module sits between them), creating emission units where the intervening module can't be correctly placed.

Test plan

  • Existing test/e2e/app-dir/css-order/ tests cover many CSS ordering scenarios across pages
  • Existing test/e2e/app-dir/initial-css-order/ tests verify correct cascade winner
  • Snapshot tests in turbopack/crates/turbopack-tests/tests/snapshot/css/split-shared/ exercise the shared batching path
  • New test/e2e/app-dir/css-order-shared-chunks/ regression test: two routes share CSS modules that interleave with route-specific modules, verifying the shared batch is emitted in the correct position relative to non-shared items so the CSS cascade order is preserved.
  • Tested the repro project referenced in many of these issues 😭

Fixes #89523 Fixes #83941 Fixes #86704 Fixes #88604 Fixes #87321 Fixes #86459

Changed files

  • test/e2e/app-dir/css-order-shared-chunks/app/a/page.tsx (added, +19/-0)
  • test/e2e/app-dir/css-order-shared-chunks/app/b/page.tsx (added, +19/-0)
  • test/e2e/app-dir/css-order-shared-chunks/app/layout.tsx (added, +11/-0)
  • test/e2e/app-dir/css-order-shared-chunks/app/page.tsx (added, +3/-0)
  • test/e2e/app-dir/css-order-shared-chunks/app/styles/shared1.module.css (added, +3/-0)
  • test/e2e/app-dir/css-order-shared-chunks/app/styles/shared2.module.css (added, +3/-0)
  • test/e2e/app-dir/css-order-shared-chunks/app/styles/unique-a-final.module.css (added, +3/-0)
  • test/e2e/app-dir/css-order-shared-chunks/app/styles/unique-a.module.css (added, +3/-0)
  • test/e2e/app-dir/css-order-shared-chunks/app/styles/unique-b-final.module.css (added, +3/-0)
  • test/e2e/app-dir/css-order-shared-chunks/app/styles/unique-b.module.css (added, +3/-0)
  • test/e2e/app-dir/css-order-shared-chunks/css-order-shared-chunks.test.ts (added, +84/-0)
  • test/e2e/app-dir/css-order-shared-chunks/next.config.js (added, +3/-0)
  • turbopack/crates/turbopack-core/src/module_graph/style_groups.rs (modified, +708/-174)

Code Example

Operating System:
  Platform: darwin
  Arch: arm64
  Version: Darwin Kernel Version 23.6.0
Binaries:
  Node: 20.9.0
  npm: 10.8.2
Relevant Packages:
  next: 15.6.0-canary.12
Next.js Config:
  output: N/A
RAW_BUFFERClick to expand / collapse

Link to the code that reproduces this issue

https://github.com/GlebKodrik/turbopack-style/

To Reproduce

Run the app in development with next dev --turbopack → Styles load correctly, no issues observed.

Build the app with next build --turbopack and then start with next start → Styles are applied in a different priority/order compared to dev mode.

Notes:

The issue reproduces 100% on our current setup. Sometimes deleting the pages folder or a random component in entities makes the bug disappear, which makes the behavior unpredictable.

Current vs. Expected behavior

Current vs. Expected behavior

  • Current: In production (next build --turbopack + next start), CSS order/priority differs from development, breaking the layout.
  • Expected: Style prioritization should be consistent between dev and build modes when using Turbopack.

Provide environment information

Operating System:
  Platform: darwin
  Arch: arm64
  Version: Darwin Kernel Version 23.6.0
Binaries:
  Node: 20.9.0
  npm: 10.8.2
Relevant Packages:
  next: 15.6.0-canary.12
Next.js Config:
  output: N/A

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

Turbopack

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

next build (local)

Additional context

Additional context Happens locally with next build --turbopack → next start. Cannot reproduce when running next dev --turbopack. Issue sometimes disappears after removing a random folder/component, which suggests non-deterministic style bundling.

1 image - next dev --turbopack 2 image next build --turbopack → next start

<img width="1440" height="170" alt="Image" src="https://github.com/user-attachments/assets/708f2da3-92a0-4938-8adf-2db908bdf234" /> <img width="1481" height="183" alt="Image" src="https://github.com/user-attachments/assets/3f9d77ba-ff2c-4453-acb6-151fd1dc5947" />

What's the problem? Is it possible to get any information? - https://github.com/vercel/next.js/pull/89615

extent analysis

TL;DR

The issue can be mitigated by investigating and potentially adjusting the CSS bundling and prioritization in Turbopack for production builds.

Guidance

  • Investigate the differences in CSS handling between next dev --turbopack and next build --turbopack followed by next start to identify why style prioritization changes.
  • Review the Turbopack configuration for any settings that might affect CSS bundling and ordering, considering the non-deterministic behavior observed.
  • Consider testing with a minimal reproducible example to isolate the issue from other project complexities.
  • Look into the discussion and potential fixes in the referenced Next.js pull request (#89615) for insights into similar issues.

Example

No specific code example can be provided without further details on the project's CSS and Turbopack configurations.

Notes

The issue seems to be related to how Turbopack handles CSS in production builds compared to development mode. The fact that deleting certain folders or components sometimes resolves the issue suggests a potential problem with how files are being bundled or prioritized.

Recommendation

Apply workaround: Adjust Turbopack configuration for CSS handling in production builds, as the issue seems related to the differences in how CSS is bundled and prioritized between development and production environments.

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