Commit Graph

1409 Commits

Author SHA1 Message Date
Luke Sandberg c54eda4baa [turbopack] Mark packages as side effect free when local analysis determines that they are. (#86398)
This implements some simple static analysis to determine if modules are side effect free based on their top level module evaluation items.

The rules are simple
 * declarations ✅ 
 * literals ✅ 
 * property access ✅  (potentially controversal but consistent with other bundlers)
 * function calls ❌  (unless part of an builtin allowlist, e.g. `Object.keys`)

imports are obviously the difficult part, for that reason we can evaluate a module to `SideEffectful` `SideEffectFree` or `ModuleEvaluationIsSideEffectFree`.  A later step will leverage a graph analysis step to determine of transitive dependencies of ModuleEvaluationIsSideEffectFree modules are also side effect free and upgrade it.

So for right now the impact is minor.  There is also an experimental option to disable it in case it causes trouble this can help us debug

I tested the performance on vercel site and as expected it isn't really observable

with side effect analysis disabled
```
~/projects/front/apps/vercel-site (main *)$ hyperfine -p 'rm -rf .next' -w 2 -r 20  'pnpm next build --turbopack --experimental-build-mode=compile'
Benchmark 1: pnpm next build --turbopack --experimental-build-mode=compile
  Time (mean ± σ):     48.017 s ±  1.696 s    [User: 319.651 s, System: 44.273 s]
  Range (min … max):   44.855 s … 50.600 s    20 runs
```

With it enabled.
```
~/projects/front/apps/vercel-site (main *)$ hyperfine -p 'rm -rf .next' -w 2 -r 20  'pnpm next build --turbopack --experimental-build-mode=compile'
Benchmark 1: pnpm next build --turbopack --experimental-build-mode=compile
  Time (mean ± σ):     48.038 s ±  2.337 s    [User: 320.261 s, System: 45.434 s]
  Range (min … max):   44.156 s … 52.774 s    20 runs
```

so if there is a regression it is well within the noise.
2025-12-11 22:22:38 -08:00
Benjamin Woodruff 85c3f2e7d7 Turbopack: bincode: Migrate TaskInput serialization to bincode (#86631)
https://github.com/vercel/next.js/pull/86338 switches cell storage to use bincode, but it uses a compatibility shim for storing `TaskInput`s using `serde` + `pot`. This PR completes the migration by switching `TaskInput` to use `bincode` as well.

## Benchmark Summary

`next build` is consistently faster across a variety of repositories when persistent caching is enabled, and the resulting cache size is consistently smaller.

![Screenshot 2025-12-01 at 9.07.20 PM.png](https://app.graphite.com/user-attachments/assets/2e19f83a-5810-4c55-b67a-aa0dd1c5da22.png)

`cargo build` runs only slightly faster, but there's potential for improving this further by removing unused `serde` macro derives.

## Benchmarking Notes

Performance measurements (aside from cargo build) are taken using `next build`​. This should have proportional benefits for `next dev`​ too, but `next build`​ is more reproducible and easier to measure. `canary` refers to `a8f7b5467485647def4c0f4479a0a83bc4a3673a`.

These numbers are taken with persistent caching enabled with an empty cache, so it's the worst-case scenario for the serialization codepath. We don't care nearly as much about the performance of deserialization because it's less common.

## `cargo build -p next-swc-napi`

This makes builds _slightly_ faster. This branch doesn't clean up the serde derives yet, so there's a bunch of unused macro expansion here, so I think this number is actually pretty good.

```
~/next.js $ hyperfine -w 1 -r 5 -p 'git co a8f7b54674 && cargo clean' -p 'git co bgw/bincode-task-inputs && cargo clean' 'cargo build -p next-swc-napi' 'cargo build -p next-swc-napi'
Benchmark 1: cargo build -p next-swc-napi
  Time (mean ± σ):     237.476 s ±  1.420 s    [User: 2001.820 s, System: 84.957 s]
  Range (min … max):   235.294 s … 238.862 s    5 runs

Benchmark 2: cargo build -p next-swc-napi
  Time (mean ± σ):     232.366 s ±  1.549 s    [User: 1945.355 s, System: 83.940 s]
  Range (min … max):   230.550 s … 234.485 s    5 runs

Summary
  cargo build -p next-swc-napi ran
    1.02 ± 0.01 times faster than cargo build -p next-swc-napi
```

## next-site

Using `~/front/apps/next-site` on macos with a M2 Pro. Nothing else was running on the machine.

```
hyperfine -p 'rm -rf .next' -w 2 -r 20 'TURBOPACK_PERSISTENT_CACHE=1 TURBO_ENGINE_IGNORE_DIRTY=1 pnpm next build --turbopack --experimental-build-mode=compile'
du -sh .next/cache/turbopack/
du -s .next/cache/turbopack/
```

#### Canary

```
Benchmark 1: TURBOPACK_PERSISTENT_CACHE=1 TURBO_ENGINE_IGNORE_DIRTY=1 pnpm next build --turbopack --experimental-build-mode=compile
  Time (mean ± σ):     14.999 s ±  0.258 s    [User: 84.137 s, System: 8.683 s]
  Range (min … max):   14.400 s … 15.509 s    20 runs
```

```
855M    .next/cache/turbopack/
1751640 .next/cache/turbopack/    (Note: macos measures size in 512B blocks)
```

#### This Branch

```
Benchmark 1: TURBOPACK_PERSISTENT_CACHE=1 TURBO_ENGINE_IGNORE_DIRTY=1 pnpm next build --turbopack --experimental-build-mode=compile
  Time (mean ± σ):     14.106 s ±  0.255 s    [User: 79.976 s, System: 8.421 s]
  Range (min … max):   13.829 s … 14.939 s    20 runs
```

```
767M    .next/cache/turbopack/
1571072 .next/cache/turbopack/    (Note: macos measures size in 512B blocks)
```

## vercel-site

Using `~/front/apps/vercel-site` on macos with a M2 Pro. Nothing else was running on the machine.

```
hyperfine -p 'rm -rf .next' -w 2 -r 20 'TURBOPACK_PERSISTENT_CACHE=1 TURBO_ENGINE_IGNORE_DIRTY=1 pnpm next build --turbopack --experimental-build-mode=compile'
du -sh .next/cache/turbopack/
du -s .next/cache/turbopack/
```

#### Canary

```
Benchmark 1: TURBOPACK_PERSISTENT_CACHE=1 TURBO_ENGINE_IGNORE_DIRTY=1 pnpm next build --turbopack --experimental-build-mode=compile
  Time (mean ± σ):     93.274 s ±  1.630 s    [User: 671.120 s, System: 57.888 s]
  Range (min … max):   91.111 s … 96.881 s    10 runs
```

```
4.3G    .next/cache/turbopack/
9002568 .next/cache/turbopack/    (Note: macos measures size in 512B blocks)
```

#### This Branch

```
Benchmark 1: TURBOPACK_PERSISTENT_CACHE=1 TURBO_ENGINE_IGNORE_DIRTY=1 pnpm next build --turbopack --experimental-build-mode=compile
  Time (mean ± σ):     88.694 s ±  0.963 s    [User: 633.801 s, System: 54.576 s]
  Range (min … max):   87.357 s … 90.037 s    10 runs
```

```
3.7G    .next/cache/turbopack/
7788472 .next/cache/turbopack/    (Note: macos measures size in 512B blocks)
```

## shadcn/ui

Using a low-noise Linux machine: https://github.com/bgw/benchmark-scripts/

```
diff --git a/apps/v4/next.config.mjs b/apps/v4/next.config.mjs
index 7fa0f012..d1137d01 100644
--- a/apps/v4/next.config.mjs
+++ b/apps/v4/next.config.mjs
@@ -27,6 +27,7 @@ const nextConfig = {
   },
   experimental: {
     turbopackFileSystemCacheForDev: true,
+    turbopackFileSystemCacheForBuild: true,
   },
   redirects() {
     return [
```

```
cd ~/shadcn-ui/apps/v4
hyperfine -p 'rm -rf .next' -w 2 'pnpm next build --turbopack --experimental-build-mode=compile'
du -sh .next/cache/turbopack/
du -s .next/cache/turbopack/
```

#### Canary

```
Benchmark 1: pnpm next build --turbopack --experimental-build-mode=compile
  Time (mean ± σ):     62.772 s ±  0.939 s    [User: 163.153 s, System: 11.170 s]
  Range (min … max):   60.739 s … 64.220 s    10 runs
```

```
596M    .next/cache/turbopack/
609636  .next/cache/turbopack/    (Note: Linux measures size in 1024B blocks)
```

#### This Branch

```
Benchmark 1: pnpm next build --turbopack --experimental-build-mode=compile
  Time (mean ± σ):     59.017 s ±  1.014 s    [User: 151.359 s, System: 9.978 s]
  Range (min … max):   57.124 s … 60.343 s    10 runs
```

```
491M    .next/cache/turbopack/
502240  .next/cache/turbopack/    (Note: Linux measures size in 1024B blocks)
```
2025-12-05 20:33:20 +01:00
Niklas Mischkulnig 7c969652ad Include nextConfig in edge runtime via separate manifest (#86769)
A separate manifest (`required-server-files.js`, like `_buildManifest.js`) so that we the bundler doesn't have to inline the whole config.

The Node.js runtime routes already get their nextConfig at runtime by reading `required-server-files.js`.

Closes https://github.com/vercel/next.js/pull/86630

Context for `initializeCacheHandlers`: https://github.com/vercel/next.js/pull/76130
2025-12-05 16:15:43 +01:00
Niklas Mischkulnig 6ff2d98c38 Turbopack: remove pages router double template (#86842)
Webpack does:
`templates/edge-ssr.js -> user's pages/index.js`

Turbopack does
`templates/edge-ssr.js { INNER_PAGE_ENTRY => \"[project]/packages/next/dist/esm/build/templates/pages.js { INNER_PAGE => \\\"[project]/test/tmp/next-test-1764875742357-479/pages/index.js`



`VAR_USERLAND` here: https://github.com/vercel/next.js/blob/ee3d017e43eb953a62746a0e6110a94dc7a3c980/packages/next/src/build/templates/edge-ssr.ts#L12-L13
for Webpack is actually the user's page file with the `export default Page()`
for Turbopack is actually whatever `templates/pages.js` exports and it relies on this default reexport: https://github.com/vercel/next.js/blob/38ef2360e1e133f329a9061ce17aad8aaab33cb2/packages/next/src/build/templates/pages.ts#L15 while ignoring everything else in there
2025-12-05 10:24:34 +01:00
Benjamin Woodruff b35713c4b5 Turbopack: bincode: Use bincode to store the contents of value cells (#86338)
This PR switches `turbo-tasks-backend` to use `bincode` instead of serde for cell contents. To keep PR size manageable, `TaskInput`s are still serialized using serde and a compatibility shim. The next PR fixes that.

See https://github.com/vercel/next.js/pull/86631 for benchmark numbers.
2025-12-05 07:36:23 +01:00
Benjamin Woodruff 2931550ebb Turbopack: bincode: Implement bincode Encode/Decode traits on all turbo task values (#85580)
It looks like bincode should reduce the filesystem cache size by ~10% versus pot, because its not a self-describing format. This attempts to add the `bincode::Encode`/`bincode::Decode` traits everywhere, so that we can use those instead of serde.

## Why not use bincode's serde compatibility feature?

- Unfortunately, serde has some bugs/incompatibilities/footguns with non-self-describing formats. `bincode`'s traits avoid this by not exposing features that would be incompatible with a self-describing format. https://docs.rs/bincode/latest/bincode/serde/index.html#known-issues
- `bincode::Encode`/`Decode` are much simpler traits than serde's equivalents, so we'll probably get some rustc build performance and turbopack binary size benefits from using the bincode versions. In cases where we do have to implement these traits by hand, it's much easier than implementing the serde equivalents.
- I'd like to kill `erased-serde` anyways because we're probably paying some performance cost from the large amounts of dynamic dispatch it performs, and we're not getting any benefits from it if we only ever serialize to a single format.

## Forks of Upstream Crates

- I've forked `bincode` here: https://github.com/bgw/bincode/commits/bgw/patches/
  - I submitted a patch via email to the maintainer via sourcehut
    - Upstream: https://git.sr.ht/~stygianentity/bincode
    - Fork: https://git.sr.ht/~bgw/bincode
  - This adds a few extra derive features and fixes type bounds on `PhantomData`.
  - The type bounds on `PhantomData` aren't very important, and we could work around it in our code.
  - We could just fork the derive crate if upstream doesn't want to accept the patches.
- And `virtue` here: https://github.com/bgw/virtue/commit/e386f35cf7f22d04a4db32231904cbe5dc52c01d
  - I've submitted a PR to `virtue` here: https://github.com/bincode-org/virtue/pull/94
  - This fixes a bug in the parsing of const enums and generics with defaults.
  - We don't hit this very often as most of our types are not generics, so we could work around it in our code if upstream doesn't want to accept the patch.

## Other Notes

- Depends on a patched version of the `bincode` and `virtue` crates to fix a few bugs and add a few new features. I'll work on upstreaming these changes.
- This implements `BorrowDecode` everywhere because the `bincode::Decode` derive macro requires it. I plan to add an attribute in my bincode fork to allow disabling this, and then we can get rid of all of the `BorrowDecode` impls. We don't want/need `BorrowDecode` for turbo task values because everything needs to be owned anyways.
2025-12-04 17:47:19 -08:00
Jiachi Liu 32dd05612a [turbopack] move edge entry wrapper to build template (#86699)
Move the edge-wrapper virtual module to templates
2025-12-03 09:57:30 +01:00
Benjamin Woodruff a05f664bb4 Turbopack: chore: Remove re-exports from turbopack crate (#85791)
I don't think these specific re-exports are too problematic, but we've moved away from the pattern of a few top-level crates re-exporting all of the rest of turbopack because in some cases it can make compilation performance much worse in the way that it structures the crate dependency graph.

Re-exports of "internal" crates can be useful in controlling what parts of the API is and isn't "public", but these re-exports aren't really doing that.
2025-12-02 14:33:26 -08:00
Luke Sandberg 342adb0e64 [turbopack] Move turbo-tasks-testing to dev-dependencies (#86745)
This is testonly so shouldn't be built as part of our release
2025-12-02 11:10:19 -08:00
Niklas Mischkulnig 2dda444c69 Turbopack: don't read binding_usage in dev (#86722)
I'm debating whether this should be `Option<BindingUsage>` instead, so that we can detect if you built the graph without the binding_usage but then still try to enable `remove_unused_exports` (which would now silently noop and never tree shaking anything).
2025-12-02 18:27:07 +01:00
Tobias Koppers 86f3bf1a6e Turbopack: avoid snapshotting while continuously idle, fix spans (#86611)
### What?

While idle only snapshot once. Start snapshotting again when idle has been left.

Place persisting spans on top level.

Fix some missing spans.
2025-12-02 14:15:53 +01:00
Pyry Takala 653cf4af0c fix(next-custom-transforms): preserve all declarators in multi-declarator export statements (#86552) 2025-12-02 13:51:12 +01:00
Niklas Mischkulnig ba8a94d2b7 Turbopack: process.env.TURBOPACK should be a string (#86680)
`process.env.FOO`  are always strings, this should be as well.
2025-12-01 17:35:15 +01:00
Niklas Mischkulnig 6eed9a0545 Turbopack: don't generateBuildId in dev (#86581) 2025-12-01 14:47:41 +00:00
Hendrik Liebau 3d30f407c4 Allow exporting object and array literals in 'use cache' files again (#86655)
In #86014 we added a validation for exporting object and array literals
from `'use cache'` files. This was a bit too restrictive, and
short-sighted, as it would prevent exporting common things like metadata
or viewport objects from page and layout files, if the file uses a `'use
cache'` top-level directive.
2025-12-01 10:01:11 +01:00
Niklas Mischkulnig 47d309af34 Turbopack: remove into() which cells internally (#86548)
This `.into()` hid the cell creation, we have already removed `.into()` as a shorthand for `Vc::cell`, but this was a manual version of that.

It could certainly be more ergonomic though:
```rust
AssetContent::file(FileContent::Content(File::from(some_str)).cell()),
```
2025-11-27 10:24:19 +01:00
Niklas Mischkulnig 112e70ed8c Turbopack: remove OptionStringifiedSourceMap (#86547)
- `OptionStringifiedSourceMap` was always a strange type
- We can now use the `FileContent` to not clone the Rope in the `SourceMapAsset::content`, which would end up duplicating sourcemaps in the cache.
2025-11-26 21:29:55 +01:00
Niklas Mischkulnig 1754f90cb7 Turbopack: slightly fewer turbo tasks calls during resolving (#86542)
The difference is barely measureable though...
```
less tasks:
  Time (mean ± σ):      5.429 s ±  0.099 s    [User: 28.337 s, System: 3.512 s]
canary:
  Time (mean ± σ):      5.547 s ±  0.082 s    [User: 28.730 s, System: 3.480 s]
```
2025-11-26 21:29:23 +01:00
Niklas Mischkulnig 7905cb4cc3 Turbopack: write symlinks to access transitive serverExternalPackages
(#86375)

Closes PACK-5936

This alleviates a long-standing painpoint of `serverExternalPackages`. If you are using
`some-utility` which uses `lodash`, and you have to make `lodash` a `serverExternalPackages`, then
you'd have to add the correct version of `lodash` to your application's dependencies in package.json.

This is not very ergonomic as it leaks the internal implementation of your direct dependencies (you
shoudln't have to care about their transitive dependencies). And it's easy to run into a situation
where it's impossible to satisfy all dependencies, if you'd have to add two conflicting versions of `lodash` for example.

Instead, Turbopack now emits symlinks like

```
.next/node_modules/lodash-98e63531e9336dd0@ -> ../../../../node_modules/.pnpm/lodash@4.17.20/node_modules/lodash
.next/node_modules/lodash-ee4fa714b6d81ca3@ -> ../../../../node_modules/.pnpm/lodash@3.10.1/node_modules/lodash
```

.so that `.next/server/chunks/29adj2sd9.js` can then contain a `require("lodash-98e63531e9336dd0")`
and alway get the correct version (and without the user having to declare them).
2025-11-26 17:05:22 +01:00
Hendrik Liebau 59fe222b5e Convert any export from a 'use cache' module to a cache function (#86014)
Previously, in a `'use cache'` module, we only compiled statically-known
exported functions and arrow expressions to cache functions. Now, we
also compile re-exports and exports of values that might be functions.

This includes exports like:
- `export { getData } from './data'` - re-exporting from another module
- `export const aliased = getData` - exporting an imported identifier
- `const Page = withSlug(...); export default Page` - exporting the
result of a function call

These cases can't be statically verified as functions at compile time,
so we generate runtime wrappers with `typeof === "function"` checks
(simplified):

```js
let $$RSC_SERVER_CACHE_getData = getData;
if (typeof getData === "function") {
    $$RSC_SERVER_CACHE_getData = React.cache(function() {
        return cache("default", "...", 0, getData, arguments);
    });
    registerServerReference($$RSC_SERVER_CACHE_getData, "...", null);
    Object.defineProperty($$RSC_SERVER_CACHE_getData, "name", { value: "getData" });
}
export { $$RSC_SERVER_CACHE_getData as getData };
```

This ensures that all function exports from `'use cache'` modules are
properly cached, while non-function exports pass through unchanged.

This approach comes with some limitations compared to statically-known
function exports:
1. **No compile-time type checking:** We can't verify that these exports
are actually functions. Non-function exports will be passed through
as-is at runtime.
2. **No async enforcement:** We can't enforce that functions must be
async (as we do for statically-known functions). Synchronous functions
are supported, but will lie about their type signature. They become
async after being wrapped as cache functions, even though their original
signature was synchronous.

closes NAR-196
2025-11-26 15:30:25 +01:00
Niklas Mischkulnig bb1a57288f Turbopack: inner graph tree shaking (#85973)
Alias "unused import removal"

Closes PACK-5782

Performance:

```
* 58fe2e2e377d877f51f91f50770310d2bbf20987 - WIP: enable by default

pnpm next build --experimental-build-mode=compile > ~/Downloads/log.txt 2>&1  380.01s user 53.74s system 691% cpu 1:02.76 total
pnpm next build --experimental-build-mode=compile > ~/Downloads/log.txt 2>&1  384.99s user 51.00s system 708% cpu 1:01.57 total
pnpm next build --experimental-build-mode=compile > ~/Downloads/log.txt 2>&1  381.52s user 46.86s system 711% cpu 1:00.21 total

vs canary:
* f6c2d49132 - Turbopack: add task_id_details feature (#84970)

pnpm next build --experimental-build-mode=compile > ~/Downloads/log.txt 2>&1  374.87s user 48.47s system 760% cpu 55.662 total
pnpm next build --experimental-build-mode=compile > ~/Downloads/log.txt 2>&1  379.18s user 50.27s system 700% cpu 1:01.28 total
pnpm next build --experimental-build-mode=compile > ~/Downloads/log.txt 2>&1  370.39s user 45.93s system 726% cpu 57.305 total
pnpm next build --experimental-build-mode=compile > ~/Downloads/log.txt 2>&1  372.70s user 46.24s system 717% cpu 58.364 total
```
2025-11-26 10:49:07 +01:00
Niklas Mischkulnig e64be50bec Turbopack: fixup route hashes generation (#86502)
Previously, it tried to compute the hash of some pages router endpoints, even they weren't in the graph (because there is no `pages` folder)
2025-11-26 10:03:08 +01:00
Hendrik Liebau acac0b0567 Fix compilation of exported server functions (#86296)
With this PR we are restructuring how the Next.js compiler transforms server function modules (`'use server'` or `'use cache'` directive at the top of the file).

The workaround for skipping the registration of exported `'use cache'` functions is removed. All exported server functions are now properly registered during visitor traversal, which fixes incorrect server reference information bytes in server reference IDs in some circumstances (see #86292 for example).

We're also adding support for string literal exports, e.g.:

```js
'use server'

async function foo() {}
export { foo as '📙' }

```
2025-11-24 13:54:17 +01:00
Tobias Koppers bb65e78ae0 Turbopack: avoid embedding deployment ID into the turbopack runtime (#86370)
### What?

* add support for multiple options for chunk suffix
* Use FromScriptSrc chunk suffix to avoid depending on deployment id
* fix passing chunk suffix to WebWorkers initial chunks
2025-11-24 09:02:58 +01:00
Tobias Koppers a49cd42955 Revert "Turbopack: remove Asset supertrait from Module trait. Modules don't have content" (#86415)
Reverts vercel/next.js#86339
2025-11-22 11:52:32 +01:00
Niklas Mischkulnig d93f4c8064 Migrate to VisitMut (#86347)
This is generally better for performance
2025-11-21 20:02:00 +01:00
Niklas Mischkulnig 33e1764252 Bump swc to 48 (#86240)
Upgrade swc from 45 to 48

Based on #85540

- In the AST, strings now contain a `Wtf8Atom` (= not utf8), while `Ident`s keep using the utf8 `Atom`.
- swc's comment printing logic also changed slighted, moving some comments around
- ~~Some comments are getting lost along the way and/or attached to the wrong line. This also broke server actions which rely on a `__next_internal_client_entry_do_not_use__` at the very top~~
2025-11-21 12:47:13 +01:00
Niklas Mischkulnig 10e0828fb9 Use JSONC for default server-external-packages (#86252)
So that we can then use comments to track a reason why we have added packages to this list.
2025-11-21 11:45:39 +01:00
Tobias Koppers e9a3ba935f Turbopack: fix import chain by determining depth locally per route (#86350)
### What?

fix the import chain showing only modules relevant to the current route

fix module graph being merged by path. It's keyed by identifier now.

also add more info to import chain, e. g. layer info. and more details in tooltip.
2025-11-21 11:39:18 +01:00
Tobias Koppers afec7a52dd Turbopack: remove Asset supertrait from Module trait. Modules don't have content (#86339)
Turbopack: remove Asset supertrait from Module trait. Modules don't have content

remove unneeded Asset implementation

<!-- Thanks for opening a PR! Your contribution is much appreciated.
To make sure your PR is handled as smoothly as possible we request that you follow the checklist sections below.
Choose the right checklist for the change(s) that you're making:

## For Contributors

### Improving Documentation

- Run `pnpm prettier-fix` to fix formatting issues before opening the PR.
- Read the Docs Contribution Guide to ensure your contribution follows the docs guidelines: https://nextjs.org/docs/community/contribution-guide

### Fixing a bug

- Related issues linked using `fixes #number`
- Tests added. See: https://github.com/vercel/next.js/blob/canary/contributing/core/testing.md#writing-tests-for-nextjs
- Errors have a helpful link attached, see https://github.com/vercel/next.js/blob/canary/contributing.md

### Adding a feature

- Implements an existing feature request or RFC. Make sure the feature request has been accepted for implementation before opening a PR. (A discussion must be opened, see https://github.com/vercel/next.js/discussions/new?category=ideas)
- Related issues/discussions are linked using `fixes #number`
- e2e tests added (https://github.com/vercel/next.js/blob/canary/contributing/core/testing.md#writing-tests-for-nextjs)
- Documentation added
- Telemetry added. In case of a feature if it's used or not.
- Errors have a helpful link attached, see https://github.com/vercel/next.js/blob/canary/contributing.md


## For Maintainers

- Minimal description (aim for explaining to someone not on the team to understand the PR)
- When linking to a Slack thread, you might want to share details of the conclusion
- Link both the Linear (Fixes NEXT-xxx) and the GitHub issues
- Add review comments if necessary to explain to the reviewer the logic behind a change

### What?

### Why?

### How?

Closes NEXT-
Fixes #

-->
2025-11-21 10:24:14 +01:00
Tobias Koppers c42d0e3d27 Turbopack: decode url encoding and relative paths in source maps (#86342)
### What?

decode url encoding and relative paths in source maps
2025-11-21 06:15:36 +01:00
Tobias Koppers f7b7f3c14f Turbopack: add NEXT_TURBOPACK_WRITE_ROUTES_HASHES_MANIFEST to write hashes into manifest (#86257)
### What?

Add an env var to write route hashes into a diagnostics file.
2025-11-20 22:47:20 +01:00
Tobias Koppers 95a074403f Turbopack: disable input source maps for analyze (#86341)
fixup

Turbopack: disable input source maps for analyze

<!-- Thanks for opening a PR! Your contribution is much appreciated.
To make sure your PR is handled as smoothly as possible we request that you follow the checklist sections below.
Choose the right checklist for the change(s) that you're making:

## For Contributors

### Improving Documentation

- Run `pnpm prettier-fix` to fix formatting issues before opening the PR.
- Read the Docs Contribution Guide to ensure your contribution follows the docs guidelines: https://nextjs.org/docs/community/contribution-guide

### Fixing a bug

- Related issues linked using `fixes #number`
- Tests added. See: https://github.com/vercel/next.js/blob/canary/contributing/core/testing.md#writing-tests-for-nextjs
- Errors have a helpful link attached, see https://github.com/vercel/next.js/blob/canary/contributing.md

### Adding a feature

- Implements an existing feature request or RFC. Make sure the feature request has been accepted for implementation before opening a PR. (A discussion must be opened, see https://github.com/vercel/next.js/discussions/new?category=ideas)
- Related issues/discussions are linked using `fixes #number`
- e2e tests added (https://github.com/vercel/next.js/blob/canary/contributing/core/testing.md#writing-tests-for-nextjs)
- Documentation added
- Telemetry added. In case of a feature if it's used or not.
- Errors have a helpful link attached, see https://github.com/vercel/next.js/blob/canary/contributing.md


## For Maintainers

- Minimal description (aim for explaining to someone not on the team to understand the PR)
- When linking to a Slack thread, you might want to share details of the conclusion
- Link both the Linear (Fixes NEXT-xxx) and the GitHub issues
- Add review comments if necessary to explain to the reviewer the logic behind a change

### What?

### Why?

### How?

Closes NEXT-
Fixes #

-->
2025-11-20 16:54:08 +01:00
Tobias Koppers 5aad91421f Turbopack: add experimental.turbopackInputSourceMaps and respect serverSourceMaps (#86340)
<!-- Thanks for opening a PR! Your contribution is much appreciated.
To make sure your PR is handled as smoothly as possible we request that you follow the checklist sections below.
Choose the right checklist for the change(s) that you're making:

## For Contributors

### Improving Documentation

- Run `pnpm prettier-fix` to fix formatting issues before opening the PR.
- Read the Docs Contribution Guide to ensure your contribution follows the docs guidelines: https://nextjs.org/docs/community/contribution-guide

### Fixing a bug

- Related issues linked using `fixes #number`
- Tests added. See: https://github.com/vercel/next.js/blob/canary/contributing/core/testing.md#writing-tests-for-nextjs
- Errors have a helpful link attached, see https://github.com/vercel/next.js/blob/canary/contributing.md

### Adding a feature

- Implements an existing feature request or RFC. Make sure the feature request has been accepted for implementation before opening a PR. (A discussion must be opened, see https://github.com/vercel/next.js/discussions/new?category=ideas)
- Related issues/discussions are linked using `fixes #number`
- e2e tests added (https://github.com/vercel/next.js/blob/canary/contributing/core/testing.md#writing-tests-for-nextjs)
- Documentation added
- Telemetry added. In case of a feature if it's used or not.
- Errors have a helpful link attached, see https://github.com/vercel/next.js/blob/canary/contributing.md


## For Maintainers

- Minimal description (aim for explaining to someone not on the team to understand the PR)
- When linking to a Slack thread, you might want to share details of the conclusion
- Link both the Linear (Fixes NEXT-xxx) and the GitHub issues
- Add review comments if necessary to explain to the reviewer the logic behind a change

### What?

### Why?

### How?

Closes NEXT-
Fixes #

-->
2025-11-20 16:22:43 +01:00
Tobias Koppers 844ec47cc3 Turbopack: remove unused method (#86259)
### What?

Method is unused
2025-11-20 14:36:10 +01:00
Tobias Koppers 8325e3c1d1 Turbopack: fix passing project options from napi (#86256)
### What?

Make stuff more type safe. Use destructuring to avoid forgetting fields
2025-11-20 13:49:50 +01:00
Hendrik Liebau 70cdb3c58a Replace tuples with better suited data structures for server references (#86294)
This PR introduces the `ServerReferenceExport` struct to replace `(Ident, Atom, Atom)` tuples for tracking exported server references. It also replaces the `Vec<(Atom, Atom)>` `export_actions` with an `FxIndexMap` for `reference_ids_by_export_name`, enabling more efficient lookups in upstack PRs. There are no functional changes.
2025-11-19 18:14:48 +01:00
Will Binns-Smith 3e5b96a17e next analyze: annotate polyfill modules in UI (#86062)
For small routes, it can appear like the polyfill chunk takes up a sizable amount of data, but `polyfill-nomodule.js` is only sent to legacy browsers. This makes it clearer.

This PR enhances the bundle analyzer by adding visual indicators for polyfill chunks, and noting they're conditionally sent to modern or legacy browsers. The changes include:

- Adds a source map to polyfill chunks (for the large pre-bundled input only)
- Visually distinguished polyfill chunks in the treemap by lightening their color
- Added a "Polyfill" badge (other badges coming soon!) with text when viewing polyfill chunk details

<img width="388" height="227" alt="image" src="https://github.com/user-attachments/assets/bcebfba6-1e10-459a-9364-b6b8197cd3df" />

Fixes PACK-5826
2025-11-17 18:02:03 -08:00
Tobias Koppers 3676d7211f Turbopack: add experimental.turbopackClient/ServerSideNestedAsyncChunking (#85827)
### What?

Allow to configure nested vs flat async chunking with a new config option.

```
experimental: {
  turbopackClientSideNestedAsyncChunking: false,
  turbopackServerSideNestedAsyncChunking: true,
}
```
2025-11-17 19:06:07 +01:00
Will Binns-Smith 617ead5753 Turbopack: Add bundle analyzer UI to next build --experimental-analyze (#85788)
This adds an interactive Treemap-style bundle analyzer app to the Next.js codebase and writes a copy to disk when `next build --experimental-analyze` is run.

* It's a separate app in `apps/bundle-analyzer` as `@next/bundle-analyzer-ui` that uses `output: 'export'` to export a purely static Next.js app
* These static resources are copied into Next.js's published `dist` directory in the `next` package itself. Users never depend on `@next/bundle-analyzer-ui`
* When users run `next build --experimental-analyze`, these static resources are copied into the user's `.next/diagnostics/analyze` along with the data payloads needed to visualize the user's app

In an upcoming PR, we'll add `next experimental-analyze` that will create analysis files without build artifacts, as well as optionally start a static file server.

Test Plan: Ran `next build --experimental-analyze` in a test app and ran a static file server to run it.
2025-11-14 15:50:42 -08:00
Tobias Koppers 43e989de1b Turbopack: only enable nested async availability in production (#85728)
### What?

Adds a new mode for processing async imports (e. g. `import("...")`).

* Nested async chunking (the existing mode): Each async import creates a new availability scope so already available modules are not included again. This leads to exploring all paths in the application to create the most efficient chunk groups. The time complexity grows with the number of paths.
* Flat async chunking: Only the first async import creates a new availability scope. This makes all async imports have the same available modules (per page), no matter how deep their are nested in the application. This allows to reuse chunk groups. The time complexity is linear to the number of async imports.

The nested async chunking has a benefit when download size matters. Flat async chunking has better compile time and often less total bundle size. Therefore nested async chunking is only enabled in production for client-side assets.
2025-11-15 00:34:53 +01:00
Tobias Koppers 8c8030edf4 Turbopack: apply side effects false removal on all module types (#86133)
### What?

fix the side effects false handling for other module types. Before it did only work for ecmascript modules.
2025-11-14 20:02:58 +01:00
Tobias Koppers c43a4d126e Turbopack: add flags to AvailabilityInfo (#85771)
### What?

Change AvailabilityInfo from an enum to a struct with flags.
2025-11-14 19:43:21 +01:00
Tobias Koppers a8d73c25f9 Turbopack: Refactor output assets to allow to lazy compute output assets (#85753)
### What?

Refactor the OutputAssets of chunk groups to not eagerly return all referenced output assets from async loaders, but instead return a list of references that can be followed to get the full list.
That solves a problem that will happen when the async loaders create cycles in the output graph.
2025-11-14 16:52:55 +01:00
Niklas Mischkulnig 9375bc3d56 Turbopack: remove global_information struct (#86089)
This was always unnecessary.

Or is this worse now as there are fewer strongly consistent reads?
2025-11-14 11:41:50 +01:00
Wyatt Johnson 291aefd985 Fix 404 responses for interception routes with missing children slots (#85779)
### What?

Introduces a null-rendering default component for interception routes to
prevent 404 responses when children slots are missing.

### Why?

When rendering interception routes like `(.)[id]`, there's a segment
mismatch where the interception route lacks a children slot that the
base `[id]` route has.

**The Bug:**
Previously, the framework injected a 404 page into the missing default
slot for the children route. On platforms like Vercel, this caused full
404 RSC responses because the HTTP status code has semantic meaning for
route behavior when using cache components. This resulted in the
"unknown segment value fallback page" issue.

**Impact:**
- RSC requests for interception routes would return 404 status codes
- Platform routing behavior was incorrectly triggered by these 404
responses
- Only affects pages rendering with cache components

### How?

- Created new `default-null.tsx` builtin component that renders `null`
- Updated Rust code (`app_structure.rs`) to detect interception routes
and use the null default
- Updated webpack loader (`next-app-loader/index.ts`) to check
`isInterceptionRouteAppPath()` and inject the null default
- Removed test-specific default component that was working around this
bug
- The old `page.tsx` is still used during client navigation, so there's
no visible change to users

This ensures minimal RSC payload changes and prevents 404 status codes
while maintaining existing client-side behavior.

NAR-483
2025-11-12 18:57:32 -07:00
Sebastian "Sebbie" Silbermann cdf8f7959b Enable React's default Transition indicator behind a flag (#86000) 2025-11-12 16:54:58 +00:00
Hendrik Liebau ee6e35a19e Omit unused encryptActionBoundArgs/decryptActionBoundArgs imports (#86015)
When a module does not include any `'use server'` or `'use cache'` closures that use variables from their outer scope, the imports for `encryptActionBoundArgs` and `decryptActionBoundArgs` are unnecessary.

> [!TIP]
> Review with hidden whitespace changes.
2025-11-12 11:19:09 +01:00
Niklas Mischkulnig cff6a5df1f Turbopack: remove duplicate traversal implementations (#85853)
We had two implementations of various traversals: first for the SingleModuleGraph, and then also the more general version that can cross module graphs. Let's just use the second for everything (with just a single graph in the case of `SingleModuleGraph`)

This turned out to be a much bigger change than I had anticipated, but this was long overdue anyway.
2025-11-12 09:36:51 +01:00
Niklas Mischkulnig 87d865f6ff Turbopack: refactor evaluate to take module_graph (#85971)
For some operations, we need the module graph (e.g. determining unused exports, and for the future inner graph tree shaking).

Previously, it was constructed inside of the evaluation machinery.
2025-11-11 19:18:54 +01:00