### Why?
This PR cleans up the incremental rollout of enabling `isolatedDevBuild`
throughout the CI, as it required many test changes (x-ref:
https://github.com/vercel/next.js/pull/84043).
- https://github.com/vercel/next.js/pull/84556
- https://github.com/vercel/next.js/pull/84558
- https://github.com/vercel/next.js/pull/84559
- https://github.com/vercel/next.js/pull/84562
This PR enables `experimental.isolatedDevBuild` by default so that users
can run `next dev` and `next build` in the same directory, and they
would not conflict. This occasionally happens when developing with AI
tools, where you have a running dev server, but the Agent runs `next
build`.
### How?
- Removed `__NEXT_EXPERIMENTAL_ISOLATED_DEV_BUILD` flag and its usage
from CI and tests
- Updated tests that were not caught via rollout (e.g., missed out on
test-*-windows)
- Moved `isolatedDevBuild` option out of experimental
- Added Telemetry
Will follow up with docs.
When `experimental.cacheComponents` is enabled, the static indicator in
the Next.js DevTools is now disabled.
With Cache Components enabled, the binary static/dynamic state is no
longer accurate since routes are typically partially static and dynamic
(unless fully opted into dynamic rendering via a Suspense boundary above
the body, which is an edge case).
To avoid confusion, we're removing it for now, when the feature flag is
enabled. In the future, we will likely provide better tools that will
allow users to understand which parts of a page are prerendered and
which parts are dynamic.
In addition, this PR also improves the behavior for fully static App
Router pages (without Cache Components). Previously, we would show
"Dynamic" as default, and only flipped to "Static" when the request was
finished. Now, we're showing a spinner while the page is loading.

closes NAR-428
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" />
Previously we used the immediate queue to schedule the consecutive tasks
that would prerender and abort and page prerender. This works fine but
since React does not consider immediates as IO for async work tracking
it means we can't use it for scheduling more advanced cases like
static->runtime->dynamic where the IO that unblocks in runtime phase can
be picked up.
While React could change to include immediates as IO the argument here
is that it isn't really IO since it is immediate work while timeouts
generally have to schedule something to fire later with timeout zero
being a sort of special case where later === now.
So instead we are going to move to scheduling our consecutive tasks
using timeout as well that way we can align the Next.js and React
heuristic for identifying IO and make certain kinds of debugging easier
to implement.
The `get_page_metadata` MCP tool was incorrectly grouping browser
sessions by URL instead of counting each session individually. When
multiple browser tabs were open to the same URL, the tool would report
only 1 session instead of the actual number of sessions.
Enabling `experimental.isolatedDevBuild` required many changes to the
current workflow, so we will incrementally roll out to the tests.
Enabling on test-dev instead of test-experimental-dev because
`-experimental` CIs are filtered via `experimental-tests-manifest.json`
and they don't cover all tests. We want to enable this feature by
default so we should ensure this incremental rollout is covered on all
test cases.
The flag was enabled for `test-experimental-dev` at
https://github.com/vercel/next.js/pull/84099, and this PR moves the flag
to the `test-dev` job.
1. ~~test-experimental-dev
([link](https://github.com/vercel/next.js/pull/84099))~~
2. test-dev (here)
3. test-prod
4. test-integration
5. test-unit
6. Enable by default, remove the flag, and update the rest
x-ref: https://github.com/vercel/next.js/pull/84043
## 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>
Reverts vercel/next.js#84389
Attempt number 3, #84374 fixed propagation of bundler environment variables to vercel cli operations, to ensure the test configuration is respected.
[Deployment Tests Run 1](https://github.com/vercel/next.js/actions/runs/18146684793/job/51649631635). A fair number of failures.
[Deployment Tests Run 2](https://github.com/vercel/next.js/actions/runs/18154875270). After #84395. These still have a set of failures, but i confirmed that the deployment builds are running `webpack`.
The tests that are failing are related to 'prefetches' (test/e2e/app-dir/segment-cache/prefetch-runtime/prefetch-runtime.test.ts and test/e2e/app-dir/segment-cache/prefetch-layout-sharing/prefetch-layout-sharing.test.ts) and generally the error is a timeout. Recent deployment runs for canary releases are also failing, but on different tests.
Trying again after #[84419](https://github.com/vercel/next.js/pull/84419). [Deployment Tests Run 3](https://github.com/vercel/next.js/actions/runs/18173375427). Failures appeared flaky, rerunning failures...
1. Added functionality to change the package name in the rspack release
CI.
2. Fixed a bug in the get_resolve method of the NextExternalsPlugin.
3. Prepared the @next/rspack-core for the 1.0.0 version release.
Reverts vercel/next.js#84348 which itself reverted #84216.
In the 2nd attempt to make --turbopack a default behavior.
* adjust the Generate Pull Request States action to specify `--webpack`
* set the `IS_WEBPACK_TEST` flag in the deployment e2e tests (which are now [passing](https://github.com/vercel/next.js/actions/runs/18113062122))
* make the warning about having a webpack config without a turbopack config more verbose and consistently an error
This PR removes the deprecated sync access to Dynamic APIs.
- Removed UnsafeUnwrapped* types.
- Replaced `as unknown as UnsafeUnwrapped ` type casts to `as any` for
dev warning.
- Removed tests that expected sync access to not error.
- Removed `UntrackedExotic` functions.
- Modified tests that were accidentally doing sync access.
- Updated warnings to emphasize that it is a Promise and must be
awaited.
- Removed paragraph that states access is allowed from
`errors/sync-dynamic-apis.mdx`.
---------
Co-authored-by: Josh Story <story@hey.com>
Make Turbopack the default bundler for Next 🚀
## What
Add a `--webpack` flag so users can select webpack
Change behavior so if neither `--turbopack` or `--webpack` is set we default to Turbopack.
If we have defaulted the build to turbopack and we observe that the user has a `webpack` config in their next config but no turbopack config, then we issue a warning about this being a potential problem, if this happens during `next build` the warning becomes an error and fails the build. The solution for users is just to explicitly set `--webpack` or `--turbopack`
There were a number of subtle issues
* some users directly set the `TURBOPACK` environment variable, this PR adds support for that though users should really be passing `--turbopack` so it will not be documented
* rspack is enabled via a plugin that sets an environment variable when loading next config, which means it happens way too late!
* For builds this isn't too bad, we just have to recompute the `Bundler` after loading the config. For `dev` the parent process can get out of sync with the child, but this is only really relevant for telemetry and for that we already load the config in the parent so just defer computing `isTurboSession`.
Most of this is about fixing package.json scripts and CI builds configs.
* For package.json
* i added aliases e.g. `test-dev` == `test-dev-webpack` but preserved the old names. In the long run we will want to remove the unsuffixed aliases
* this required some modifications to existing configs to ensure everything was setting the correct env variables
* For ci, i added a new `IS_WEBPACK_TEST` variable to a number of tests but preserved all names.
* Again, in the future it would make sense to rename ci jobs but that is deferred for right now.
* This also makes it clear that a set of tests scenarios (e.g. ppr, experimental, test-new-tests-*) never run with turbopack. This is not addressed right now but should be in the future.
## Why
Today, the default bundler for next is webpack but with turbopack becoming stable it is time to just ship it. Turbopack is already recommended for dev and builds. Create Next App also steers users towards Turbopack. According to telemetry we already have about 50% of all dev sessions and build adoption is growing. So fundamentally why are we even asking users to make a decision?
This also adds a build-time test, documenting the unhelpful error messages we currently show during prerendering, when an app router file does not have a default export.
The test suite is now using fixture files instead of sandboxes, same principle as in #83398. I also removed two test cases that didn't test anything novel, compared to the other tests. They were originally moved from another test suite into this one in #66916.
This is done in preparation for adding build-time assertions.
> [!TIP]
> Best reviewed with hidden whitespace changes.
Enables AI agents to programmatically access the runtime metadata of the
current page. At the moment, we only include the segment trie details,
but this endpoint will be open to extension. Like `get_errors`, we
support collecting information from multiple tabs.
Enables AI agents to programmatically access the runtime/build errors
from the current devtool overlay of a dev session. The errors are
pretty-printed by default with source-mapped stack frames. In
particular, it supports pulling error information from multiple browser
tabs.
This PR integrates an MCP server into the Next.js development server at
`/_next/mcp`, enabling AI agents to programmatically interact with
Next.js projects. We're including an initial `get_project_path.` tool as
an example that returns the project's absolute path - this serves as a
starting point to demonstrate how tools can expose project information
to MCP clients, with plans to expand the available tools for richer
AI-assisted development experiences.
### What?
Changing an env var that is used in an RSC doesn't lead to HMR updates. It only refetches the RSC stream and no compilation happens at all since the env var is consumed only at runtime.
This test did pass before as the `run_once` created a task for the `project_update` and we counted that as computation. Changing this to `turbo_tasks::run` removes the once task and no computation happens at all.
### Why?
When running a dev server, it currently gets interrupted when running
`next build`.
This is very common when using AI for app development, where it runs
`next build` for whatever reason while the user is working on a dev
server.
### How?
This PR creates an isolated `dev/` directory inside the `distDir` to be
isolated from the build, and will not be cleared out during the `next
build` like the `cache/` directory. Since the cache between the dev and
prod isn't shared at the moment, it makes sense to let them have
separate `cache/` directories.
https://github.com/user-attachments/assets/2005ba70-861c-4763-b47f-cf17c62c0571
This commit addresses the bugs where Hot Module Replacement (HMR) was
not functioning correctly in Rspack mode. Component edits would often
result in no update or a full page reload instead of a fast,
state-preserving refresh.
This commit implements a new, custom React Refresh plugin and runtime
specifically for Rspack, which correctly orchestrates the HMR lifecycle.
After fixing the workflow config for Rspack in #83677, we're now running
more Rspack tests with React 18 on the `canary` branch. A few snapshot
tests now need to be updated because of that. The special cases are the
same as what we already had for Turbopack + React 18.
While dogfooding the debug channel in internal applications, we found
bugs (most likely in React) that trigger runtime errors, when the debug
channel is used to transport debug information. Those need to be
investigated and fixed first, before we can enable the feature by
default.
In dev mode, React is sending debug info (owners, stacks, console logs
etc.) from the server to the client so that they can be displayed in dev
tools. By default, this info is sent as part of the main RSC payload
(inlined into the HTML, or fetched after interaction). With this PR,
we're now transporting the debug info in a separate debug channel. This
channel currently consists of a unidirectional stream (writable on the
server, readable in the client) that is serialized as binary WebSocket
messages, which are sent through the existing WebSocket connection that
Next.js uses for HMR messages etc.
In a follow up, we will also implement the return channel (writable in
the client, readable on the server). This allows the client to retrieve
debug info lazily and on demand during inspection/introspection.
One benefit of this approach is, that it will allow us to change our
dynamic validation strategy. We should then be able to tee and cut off
the dynamic RSC stream at different points in time (representing the
static prerender, runtime prerender, and dynamic render stages), while
still letting the complete debug info stream in through the separate
channel. This allows us to show the same dynamic validation error
details as before, while reducing the number of renders needed to
accomplish that.
For dogfooding purposes, the feature can be disabled by setting
`experimental.reactDebugChannel` to `false`, in case of unexpected
regressions in dev mode.
### An implementation note on the request ID handling
On the server, at the beginning of the rendering process, we determine a
`requestId` and an `htmlRequestId`.
1. The `requestId` is a UUID that's newly generated for each incoming
request.
2. The `htmlRequestId` is one of two things:
1. For the HTML request, it's the same as the `requestId`.
2. For subsequent RSC requests (for navigations or server actions), it's
the ID of the HTML document from where the request originates. It is
sent as the `x-nextjs-html-request-id` request header.
The HTML request ID is used to identify connected WebSocket clients.
It's sent to the browser as the global `__next_r` variable in the script
tag that also includes the initial RSC instructions. The browser sends
it back to the server as `id` query param of the WebSocket request. On
the server, we store the clients by HTML request ID. When debug chunks
are sent to the browser, we use the HTML request ID to look up the
correct client. (There's only one client per browser tab/window.)
In the browser, we create a debug channel for each request, and we store
them keyed by request ID. For the HTML request, the request ID from
`__next_r` is used as key. For the RSC requests, the `requestId` is
received as `x-nextjs-request-id` response header, and used as key. The
server sends the current request ID as part of the WebSocket message to
the browser, so that the chunks can be enqueued into the correct debug
channel.
closes NAR-310
## What?
These values were only provided to emit events and not for the actual
handling of jsconfig/tsconfig `paths` and such, those are handled
separately by Turbopack itself. This removes the events as they're no
longer relevant and it's not worth slowing down dev/build for them.
## Fix handling of intercept route segments in HMR
### What?
- Made the routes in `resolve-routes.ts` get lazily initialized, and
only recalculated in development mode to preserve
performance
- Added a test case for HMR with intercept routes
### Why?
This change ensures that intercept route segments (and any other changed
elements of routes), will be recalculated correctly during the
development proecess.
Fixes #PACK-5246