vercel / vercel/next.js

[Turbopack] Explore opt-in shared server output for co-deployed context-neutral graphs

Open
#97,487 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Output Turbopack
Dominant language
JavaScript
Stars
142k
Forks
32.4k
Avg merge
2d 14h
Merged PRs (30d)
351

Description

Link to the code that reproduces this issue

https://github.com/Ustay-coder/next-turbopack-cross-context-sharing-repro/tree/b4df11ee2150e8d23a997a27ac989975c1f59c39

To Reproduce
  1. Clone the public minimal App Router reproduction and check out the pinned commit b4df11ee2150e8d23a997a27ac989975c1f59c39.
  2. Install dependencies with pnpm 9.0.0.
  3. Build with next@16.3.1-canary.0 on Linux x64 (Turbopack is the default bundler).
  4. The app imports the same deterministic, context-neutral ESM/JSON graph from both an app-route entry and an app-rsc entry.
  5. Run the four-cell factorial measurement (baseline / route / action / both, three runs) documented in results/linux-x64.md and compare the gzip sizes of the emitted .next/server output.

Both runtime paths pass. The full methodology and results are in the Linux report.

Current vs. Expected behavior

Current: With Turbopack, the second context's server output retains a full second copy of the shared graph. Measured second-context gzip cost: 181,504 B (duplication ratio 0.999994). With Webpack, the same graph adds -1,043 B (effectively zero duplication). Both runtime paths pass, so this is a retained-output-size observation, not a claim about duplicate execution within one runtime.

Expected: This is deliberately an Ideas proposal, not a bug report. The question is whether Turbopack could offer an opt-in server-output strategy for a context-neutral graph when a deployment target can prove compatible runtime semantics and co-location, while preserving self-contained server endpoint output as the default. The output-size versus independent-deployment trade-off should be explicit for server contexts, rather than leaving applications with client-only chunking controls for this boundary.

Provide environment information
From the reproduction's Linux report (`results/linux-x64.md`):

Operating System:
  Platform: linux
  Arch: x64

Binaries:
  Node: v22.23.2
  pnpm: 9.0.0

Relevant Packages:
  next: 16.3.1-canary.0 (tag commit 5005bd083874d366f95fd34da7a5d27837cbd5fa)
  react: 19.2.8
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

Goals

  1. Preserve self-contained server endpoint output as the default, so routes can continue to be deployed independently when a platform requires that.
  2. Clarify whether Turbopack could offer an opt-in server-output strategy for a context-neutral graph when a deployment target can prove compatible runtime semantics and co-location.
  3. Make the output-size versus independent-deployment trade-off explicit for server contexts, rather than leaving applications with client-only chunking controls for this boundary.

Non-Goals

  1. This is not a request to merge app-route and app-rsc into one compilation context, or to change the default Lambda/function packaging model.
  2. This is not a request to share modules across different runtime targets, resolution conditions, transforms, externalization choices, side-effect semantics, or availability constraints.
  3. This is not the instanceof / singleton correctness issue tracked in #89192, and it does not require client chunking, HMR, Pages Router, or Edge/Node cross-runtime work.

Background

#89192 establishes an important constraint: multiple physical server outputs can be expected because different routes may be deployed as separate production Lambdas. I agree that self-contained endpoint output should remain the default.

The remaining question is about an optional output-size trade-off when that deployment constraint does not apply. I prepared a public, minimal App Router reproduction pinned to an immutable commit:

https://github.com/Ustay-coder/next-turbopack-cross-context-sharing-repro/tree/b4df11ee2150e8d23a997a27ac989975c1f59c39

It imports the same deterministic, context-neutral ESM/JSON graph from both an app-route entry and an app-rsc entry. On Linux x64 with next@16.3.1-canary.0, a four-cell factorial measurement with three runs found:

Bundler Second-context gzip cost Duplication ratio
Turbopack 181,504 B 0.999994
Webpack -1,043 B effectively zero

The full methodology and results are in the Linux report. Both runtime paths pass. This is therefore a retained-output-size observation, not a claim about duplicate execution within one runtime.

I also checked the recently added experimental.turbopackChunking controls. They expose client chunk-group merging choices, but I could not find an equivalent server-output strategy for this app-route / app-rsc boundary.

Proposal

Would the team be open to defining an opt-in mechanism for this trade-off, while keeping independent, self-contained server outputs as the default?

I am intentionally not proposing a source-hash-only deduplication algorithm. Any sharing would need to establish equivalence of at least the emitted module factory, resolution/condition set, transforms, dependency edges, runtime, externalization, side effects, and async availability.

Two possible directions seem worth discussing:

  1. Adapter-consumable manifest or shared artifact. Next.js could describe a reusable server graph and its requirements, while a deployment adapter that guarantees co-location could choose to package it once. Without such an adapter, endpoint outputs would remain self-contained.
  2. Explicit experimental server-output strategy. Turbopack could expose a narrowly scoped, deployment-aware mode for compatible Node server contexts. This would make the size trade-off visible to users, but would carry a broader support and compatibility surface.

Would either direction fit the intended Next.js boundary, or is this fundamentally a deployment-adapter concern that should be documented outside Turbopack? If the team sees a viable contract, I can contribute a narrowly scoped regression fixture after the supported contexts and semantic exclusions are agreed.


Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by running the pinned reproduction and reading results/linux-x64.md, then review the experimental.turbopackChunking controls in PR #96398. Compare the reported Turbopack and Webpack output behavior and determine whether a supported server-output contract or deployment-adapter boundary can be defined; done requires an agreed direction before implementing a regression fixture.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript, next.js, react
Domain
build-system
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Quiet
Clarity
Needs clarification
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.