Previously we would `eprintln!` in this case, but that is missing key source information that would help with debugging.
Example warning (i hacked the limit to be lower to make this less tedious to repro):

If there are more than 10K matches we will issue this warning.
A tricky thing is that because we issue this warning during the module graph construction, but `resolve_reference` won't be called again for a FileSource reference during chunking the issue actually wouldn't get emitted. The fix is to drop the `take_issues` call inside of `whole_app_module_graphs` in production builds.
### What?
Adds build-time validation to require explicit `default.js` files for
all parallel route slots (except the implicit "children" slot). This
validation is implemented in both Webpack and Turbopack bundlers.
### Why?
Parallel routes without `default.js` files currently cause silent 404
errors when users navigate to those routes. This creates confusion and
hard-to-debug issues because the routes appear to be configured
correctly but fail at runtime without any indication of what went wrong.
By making this validation explicit at build time, developers get
immediate feedback about missing required files with clear error
messages and documentation links, catching configuration mistakes before
deployment.
### How?
**Rust/Turbopack** (`crates/next-core/src/app_structure.rs`): Added
`MissingDefaultParallelRouteIssue` that emits a build error when a
parallel route slot is missing its `default.js` file. The validation is
skipped for the "children" slot since it's implicit and doesn't require
a default file.
**Webpack**
(`packages/next/src/build/webpack/loaders/next-app-loader/index.ts`):
Added validation that throws `MissingDefaultParallelRouteError` when
`default.js` cannot be resolved. The "children" slot falls back to the
existing `PARALLEL_ROUTE_DEFAULT_PATH` behavior for backward
compatibility.
**Error Class**
(`packages/next/src/shared/lib/errors/missing-default-parallel-route-error.ts`):
New error type with helpful messaging that includes the slot path,
explanation of the requirement, and a link to documentation.
**Migration Path**: Users who want the previous 404 behavior can
explicitly create a `default.js` that calls `notFound()`, or return
`null` for empty slots:
```tsx
import { notFound } from 'next/navigation'
export default function Default() {
notFound()
}
```
Users can also run the following Deno script to generate the default
files for them:
https://gist.github.com/wyattjoh/ba7263ecb637ef399d3e3e4db63ffbd6
**Breaking Change**: This is a breaking change timed for Next.js 16
beta. Builds will now fail if parallel route slots are missing required
`default.js` files.
This PR adds a two new options and sets a strict default value for each.
- `images.dangerouslyAllowLocalIP`
- `images.maximumRedirects`
### dangerouslyAllowLocalIP
In rare cases when self-hosting Next.js on a private network, you may
want to allow optimizing images from local IP addresses on the same
network.
However, this is not recommended for most users so the default is
`false`.
> [!NOTE]
> BREAKING CHANGE: This change is breaking for those who self-hosting
Next.js on a private network and want to allow optimizing images from
local IP addresses on the same network. In those cases, you can still
enable the config.
### maximumRedirects
Since are also testing redirects for local IPs, we can also reduce the
maximum number of redirects to 3 by default.
Unlike normal websites which might redirect for features like auth, its
unusual to have more than 3 redirects for an image.
In some rare cases, developers may need to increase this value or set to
`0` to disable redirects.
> [!NOTE]
> BREAKING CHANGE: This change is breaking for those who need image
optimization to follow more than 3 redirects.
We took a look at unique Next.js projects that have one or more requests
for a specific image size and here are the findings as seen from the
Image Optimization API:
- `w=16` 4.2%
- `w=32` 17.1%
- `w=48` 21.4%
- `w=64` 22.6%
- `w=96` 25.8%
- `w=128` 29.5%
- `w=256` 46.5%
- `w=384` 35.1%
- `w=640` 57.2%
Only 4.2% of Next.js projects ever made a request to a 16px width image.
This is low enough to remove from the default configuration so that all
other projects can benefit from reduced html
[srcset](https://developer.mozilla.org/en-US/docs/Web/API/HTMLImageElement/srcset)
and fewer variations exposed from the backend API.
You might think that this means few developers are using `<Image
width={16} />` but it probably means that most displays nowadays use
devicePixelRatio 2 meaning that specifying a 16px image width will
actually fetch the 32px width to ensure it won't looking blurry on your
retina display.
BREAKING CHANGE: this is technically a breaking change but it won't
cause apps to stop working, its just 4% of them may have some requests
serve a 32px image instead of 16px. Those apps can of course opt in by
changing their `images.imageSizes` config back to allowing 16.
We recommend users avoid relying on Middleware unless no other options
exist. Our goal is to give them APIs with better ergonomics so they can
achieve their goals without Middleware.
The term “middleware” often confuses users with Express.js middleware,
which can encourage misuse. To clarify our direction, we are renaming
the file convention to “proxy.” This highlights that we are moving away
from Middleware, breaking down its overloaded features, and making the
Proxy clear in its purpose.
`proxy.js` should be a drop-in replacement for `middleware.js` for its
features, but ONE thing:
```diff
- export function middleware
+ export function proxy
```
Codemod: https://github.com/vercel/next.js/pull/84127
---------
Co-authored-by: Benjamin Woodruff <benjamin.woodruff@vercel.com>
In https://github.com/vercel/next.js/pull/83003, `legacyBehavior` and
`passHref` were removed from `<Link>`. However, this turned out to be a
bit premature—despite most usage being covered by the newer `<Link>`
APIs, there's some use cases we don't yet have good alternatives for.
We expect to solve this with an API that uses Fragment Refs once they're
available in React. For now, we're re-enabling these flags.
---------
Co-authored-by: JJ Kasper <jj@jjsweb.site>
### Why?
When the user hasn't set a matcher in the middleware, it always hits the
internal route `/_next/`. This is redundant, though quite common, as it
serves all the static assets. Therefore, skip the internal route by
default when no matcher is set.
---------
Co-authored-by: JJ Kasper <jj@jjsweb.site>
Co-authored-by: vercel[bot] <35613825+vercel[bot]@users.noreply.github.com>
https://github.com/vercel/next.js/pull/83961 lets you run both `next dev` and `next build` at the same time, however it's still problematic to run two instances of `next dev` or two instances of `next build` at the same time with the same `distDir`.
This sort of thing can happen to anyone by accident, but we've seen reports of this sort of behavior with AI agents.
https://github.com/vercel/next.js/pull/84378 adds a lockfile around just the persistent cache database in Turbopack, which helps, but it's not the only reason this is problematic, so we also need a lock around all of Next.js itself.
I was not able to find a cross-platform lockfile implementation in node that I felt was of sufficient quality, so on POSIX platforms this uses the recently-stabilized Rust stdlib implementation, which appears to be derived from rustc's own lockfile implementation, which has seen widespread use/deployment.
On Windows, since we'd rather have an advisory lock than a mandatory one, this emulates that by instead opening a file with write permissions, and a sharing mode that prohibits shared write access. That means that other processes can safely read the (empty) lockfile without blowing up.
<img width="500" src="https://github.com/user-attachments/assets/1ee4a6c6-2280-4f64-8bf2-ec5369c26db1" />
<img width="500" src="https://github.com/user-attachments/assets/2b04b566-c0b4-42ce-af34-912f3f6afa72" />
Tested on Windows as well:
<img width="1224" height="690" alt="Screenshot 2025-10-07 at 5 44 33 PM" src="https://github.com/user-attachments/assets/e36085b6-9c32-40ac-aca6-4c83e2a53842" />
## Improve error message when Next.js package can't be found
### What?
Enhances the `get_next_package` function to provide a more informative
error message when the Next.js package cannot be found from the context
directory.
### Why?
When users encounter issues with Next.js package resolution, the
previous generic error message "Next.js package not found" didn't
provide enough context or guidance on how to fix the problem. The
improved error message explains potential causes and solutions.
### How?
- Updated the function to use Vc<FileSystemPath> for context_directory
- Improved error handling with a detailed message that:
- Explains the issue clearly
- Shows the context directory path where resolution failed
- Suggests setting `turbopack.root` in the Next.js config
- Mentions potential issues with symlinks
- Provides a link to documentation for more information
### How to Test
To test this,
1. Modify `<projectRoot>/bench/basic-app/next.config.js` to
```js
module.exports = {
experimental: {
serverMinification: true,
},
turbopack: {
root: __dirname,
}
}
```
2. Run `pnpm build && pnpm swc-build-native` to ensure that you have the
updated code
3. Run `pnpm next dev --turbo bench/basic-app` and ensure the error
shows up exactly once
4. Run `pnpm next build --turbo bench/basic-app` and ensure the same
error shows up exactly once
---------
Co-authored-by: Niklas Mischkulnig <4586894+mischnic@users.noreply.github.com>
Co-authored-by: Luke Sandberg <lukeisandberg@gmail.com>
### What?
* avoid dependencies due to tracing
* Avoid invalidating client chunking context when chunk_suffix_path changes
* BrowserChunkingContext::chunk_path only depends on a selected subset of fields
* select cross_origin field instead of depending on the whole config
* select NextConfig::output field instead of depending on the whole config
* make all next config fields private to ensure using selector functions
Turns string decode and parse errors into warnings for extensionless files when in tracing mode.
A `require(dynamic)` inside of node_modules can easily end up pulling in extensionless files such as binary files, or `LICENSE`, which would fail the build.
## What?
Add a new feature to turbopack for generating debug_ids based on the
[TC39 Debug ID
proposal](https://github.com/tc39/ecma426/blob/main/proposals/debug-id.md)
If a user sets `turbopack.debugIds = true` then we will
* register the debug id with the global `_debugIds` object
* this object is keyed by a stack trace for the script. This enables
associating debug ids with stack frames when reporting errors.
* add a ` //# debugId=XXX` comment at the end of the generated code
* add a `"debugId": "XXX"` property to the source map json file
The debug id value is a hash of the file contents using the
`xxhash3_128` hash algorithm represented as a UUID hyphentated string.
One oddity is Indexed source maps. Turbopack uses indexed source maps
for simple performance and 'incremental execution' reasons, but the
debug id spec says that debugIds only apply to non-indexed source maps.
Reading between the lines (thanks @bgw! ), this appears to be a simple
spec issue related to older versions of the indexed-source maps
specification. Adding the debugId to the indexed map is unlikely to be
harmful and the authors agree this should be covered ([see
issue](https://github.com/tc39/ecma426/issues/203)).
## Why?
Debug Ids make javascript source files and source maps self identifying
without relying on URLs. This improves the ability for offline processes
to ensure a proper association regardless of how sources our source maps
are served.
## How?
* thread the `debug_ids` bit from the next config down to the chunking
context and finally to the `Code` structs
* implement a uuid generator that can content address the code to
generate the id
- neither content addressing nor even determinism are _required_ by the
spec but this is the simplest approach. We could use a simple 128 bit
random number, but this is chaotic and goes against our own natural
desires for determinism.
* compute the debug id in a turbotask on the `Code` struct and embed
when generating chunks and source maps.
* add a few tiny snapshot tests to demonstrate the feature.
Fixes PACK-417
---------
Co-authored-by: Tim Neutkens <tim@timneutkens.nl>
Previously, you could have duplicate NFT modules (and duplicate analysis):
- user code ESM imports external `twoslash` which loads `typescript`
- user code CJS imports external `ts-morph` which loads `typescript`
Both cases would get different asset contexts, due to `externals_tracing_module_context(ExternalType::CommonJS)` vs `externals_tracing_module_context(ExternalType::Esm)`
<img width="2560" height="856" alt="Bildschirmfoto 2025-09-30 um 11 00 18" src="https://github.com/user-attachments/assets/7604783b-6e16-4b34-9af3-d8aa65a0cff8" />
This replacement should only happen in dev, it's really only to be able to have nicer error messages.
This previously failed the deployment tests.
Related: https://github.com/vercel/next.js/issues/40625
Closes PACK-5591
* don't construct a `cell` just use an `Arc`
* this will make it possible to call `peek_issues` in a top level transient task
* This required making `AutoSet` `TaskInput` compatible. The downside is that a few tasks get a more complicated hash/eq implementation for their inputs but the `DelegatingInputTracer` value is generally very small so this should be fine.
* these functions are no longer async or failable, so simplify the signature
We've received feedback that this log line is more confusing than useful.
In the future, we'd like to show this, but in a more clear and structured way, along with other metrics for other parts of the build.
Pages router data endpoints are only needed or used in `dev` but we would unconditionally create them even in `build` scenarios`.
This clarifies the API and modifies `endpoint` collection to also collect these when they exist. This will unblock enabling the `whole_app_module_graph`
https://github.com/vercel/next.js/pull/77850 moved `experimental.turbo`
option to `turbopack`, but `moduleIds` is intended for debugging, in
line with `turbopackSourceMaps` and `turbopackMinify`, so move to
`experimental.turbopackModuleIds`.
- In development, it's "named" by default, and making it "deterministic"
breaks HMR.
- In production, it's "deterministic" by default, and making it "named"
blows up bundle sizes and exposes your internal project structure in the
module ID strings.
Lazily compute the contents of the client reference and the font manifests, this moves the computation to `emit` (= writing out all chunks in parallel) as opposed to `Endpoint::output` (= where we are determining the list of chunks to emit).
<img width="1891" height="910" alt="Bildschirmfoto 2025-09-24 um 18 30 13" src="https://github.com/user-attachments/assets/3d3dbd83-4125-4bb5-bb90-e38c536cc44e" />
Add a JS module type that does no analysis, and just concatenates the source file into the output file.
As a consequence however, the input module cannot have
- `import`s/`require`s/`new Worker`/...
- ~~`process.env.*` that should be replaced~~
- JSX/any new syntax, since the module won't be transpiled using the user's browserslist
```
before:
✓ Starting...
✓ Ready in 335ms
○ Compiling / ...
✓ Compiled / in 980ms
GET / 200 in 1258ms
after:
✓ Starting...
✓ Ready in 406ms
✓ Compiled / in 406ms
GET / 200 in 692ms
```
<img width="1358" height="959" alt="Bildschirmfoto 2025-09-16 um 12 09 47" src="https://github.com/user-attachments/assets/87bb3161-8749-475b-9a84-bf62324735e4" />
<img width="1352" height="939" alt="Bildschirmfoto 2025-09-16 um 12 12 48" src="https://github.com/user-attachments/assets/4a42e724-7090-4ca7-bad9-41e5cf1af80b" />
The `affecting_sources` field on `ResolveResult` and `ModuleResolveResult` are used for file tracing, but not for normal builds. So make tracking this information conditional.
This will be a minor performance win for a few reasons
* no allocations to store these lists
* no storing this data in the PC database
* changes to affecting sources won't invalidate resolution results.
Closes PACK-5438
It compiles fine, but we have another problem: `cargo fmt` really doesn't like it
```
cargo fmt -- turbopack/crates/turbo-tasks-fs/src/lib.rs
error: let chains are only allowed in Rust 2024 or later
--> /Users/niklas/code/next.js/turbopack/crates/turbo-tasks-fs/src/lib.rs:749:44
|
749 | if create_directory && let Some(parent) = full_path.parent() {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: let chains are only allowed in Rust 2024 or later
--> /Users/niklas/code/next.js/turbopack/crates/turbo-tasks-fs/src/lib.rs:893:44
|
893 | if create_directory && let Some(parent) = full_path.parent() {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: let chains are only allowed in Rust 2024 or later
--> /Users/niklas/code/next.js/turbopack/crates/turbo-tasks-fs/src/lib.rs:1233:12
|
1233 | if let Some(path) = join_path(&self.path, path)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
```
The precommit hook that selectively runs on files is simply not a supported usecase.
So I changed that to `rustfmt --edition 2024 -- ` now 🤷
Previous discussion: https://vercel.slack.com/archives/C03EWR7LGEN/p1748898285716779
In error messages and in docs for `'use cache'` and related APIs, we now
guide users to the `experimental.cacheComponents` config instead of
`experimental.useCache`.
closes NAR-410
### What?
`referenced_output_assets` are different for every chunk group. Attaching them as references to a random chunk in the group causes a different Chunk instance which not only causes duplicate work, but also multiple writes to the same file.
This fixes that by refactoring that and attaching the `referenced_output_assets` higher. Actually it simplifies it.
Closes PACK-4322
Closes PACK-4392