nextjs - ✅(Solved) Fix Turbopack standalone build in 16.1.x omits serverExternalPackages from .next/standalone/node_modules [1 pull requests, 8 comments, 7 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#88844Fetched 2026-04-08 02:03:50
View on GitHub
Comments
8
Participants
7
Timeline
40
Reactions
19
Author
Timeline (top)
subscribed ×19commented ×8labeled ×4cross-referenced ×2

Error Message

Error: Cannot find module 'ts-deepmerge'

Root Cause

Because the final image is based on a distroless Node.js image and does not run pnpm install (by design), there is no way for the missing dependency to be resolved at runtime.

Fix Action

Fix / Workaround

export default nextConfig;

4. Import and use ts-deepmerge in any server-side file (e.g. `page.tsx`)
5. Run the build using Turobopack
```bash
next build
  1. Inspect the generated standalone output:
ls .next/standalone/node_modules

Observed result

  • ts-deepmerge is not present in .next/standalone/node_modules.

Workaround If I run the build using Webpack instead:

next build --webpack

The generated .next folder has ts-deepmerge inside .next/standalone/node_modules folder.

PR fix notes

PR #895: fix: drop --turbopack from production build

Description (problem / solution / changelog)

Summary

Reverts the --turbopack flag on the build script added by KEEP-284 (00f01ce4). Keeps the RUN --mount=type=cache,target=/app/.next/cache line in the Dockerfile (it's harmless with webpack and leaves scaffolding for a future re-enable).

Why

Next.js 16.1.x ships Turbopack as stable for production, but its output: "standalone" tracer has an active regression: it silently omits packages listed in serverExternalPackages from .next/standalone/node_modules/ (vercel/next.js#88844). Our next.config.ts has a large serverExternalPackages list covering @workflow/*, pg, drizzle-orm, etc., so the Turbopack standalone output is effectively incomplete.

The bug manifests non-deterministically: a fresh build sometimes produces a working standalone, but as soon as BuildKit reuses a cached layer containing a bad Turbopack state, the runner image fails at startup. Symptoms in the container logs:

Error: Cannot find module 'next'
Require stack: /app/server.js

Evidence this is what's happening

  1. Staging CI on main (post-merge) has been failing at the e2e-vitest-ephemeral / Start application step since Turbopack was enabled (last failed run). The build job reports #40 [app builder 2/2] RUN ... pnpm build as CACHED, then the runner stage can't resolve next.
  2. The previous green staging run (24577197990) had the same Dockerfile/package.json but a fresh (non-cached) pnpm build. Turbopack happened to emit a complete standalone that time, so the app booted.
  3. Prod deploys don't catch it because ENABLE_E2E_EPHEMERAL_TESTS is only true on staging; on prod the runtime e2e job is skipped. Any broken image produced on prod would ship silently and surface only via pod CrashLoopBackOff.
  4. Local repro confirmed: a Docker build of the runner target with --turbopack removed boots cleanly (Next.js 16.2.2 Ready in 0ms).

Scope of revert

  • package.json: next build --turbopack -> next build. One line.
  • Dockerfile: unchanged.
  • next.config.ts: unchanged (its outputFileTracingIncludes + serverExternalPackages lists are still correct for webpack).

Follow-up

  • Track vercel/next.js#88844. Re-enable --turbopack once the standalone omission is fixed upstream.
  • Consider enabling runtime e2e (ENABLE_E2E_EPHEMERAL_TESTS=true) on the prod CI gate so image-start regressions are caught before they reach pods.

Changed files

  • package.json (modified, +1/-1)

Code Example

import type { NextConfig } from "next";

const nextConfig: NextConfig = {
  output: "standalone",
  serverExternalPackages: ["ts-deepmerge"],
};

export default nextConfig;

---

next build

---

ls .next/standalone/node_modules

---

Error: Cannot find module 'ts-deepmerge'

---

next build --webpack

---

Operating System:
  Platform: darwin
  Arch: arm64
  Version: Darwin Kernel Version 25.2.0: Tue Nov 18 21:09:34 PST 2025; root:xnu-12377.61.12~1/RELEASE_ARM64_T8112
  Available memory (MB): 8192
  Available CPU cores: 8
Binaries:
  Node: 22.22.0
  npm: 10.9.4
  Yarn: 1.22.22
  pnpm: 10.28.0
Relevant Packages:
  next: 16.1.4 // Latest available version is detected (16.1.4).
  eslint-config-next: N/A
  react: 19.2.3
  react-dom: 19.2.3
  typescript: 5.9.3
Next.js Config:
  output: standalone

---

.next/
└─ standalone/
   ├─ .next
   ├─ server.js
   ├─ package.json
   ├─ node_modules/
   │  └─.pnpm
   │  └─next
   │  └─react
   │  └─react-dom
   │  └─ts-deepmerge
   │  └─typescript

---

next build --webpack

---

COPY --from=builder /app/.next/standalone ./
COPY --from=builder /app/.next/static ./.next/static
RAW_BUFFERClick to expand / collapse

Link to the code that reproduces this issue

https://github.com/MTroian94/next-16.1.4

To Reproduce

  1. Create a new Next.js app using Next.js 16.1.x with Turbopack enabled.
  2. Install a dependency that will be externalized, for example: pnpm add ts-deepmerge
  3. Configure next.config.ts with output: "standalone" and serverExternalPackages:
import type { NextConfig } from "next";

const nextConfig: NextConfig = {
  output: "standalone",
  serverExternalPackages: ["ts-deepmerge"],
};

export default nextConfig;
  1. Import and use ts-deepmerge in any server-side file (e.g. page.tsx)
  2. Run the build using Turobopack
next build
  1. Inspect the generated standalone output:
ls .next/standalone/node_modules

Observed result

  • ts-deepmerge is not present in .next/standalone/node_modules.

Current vs. Expected behavior

Current behavior (Next.js 16.1.x + Turbopack) When building a project with:

  • output: "standalone"
  • serverExternalPackages configured
  • default Turbopack build (next build)

dependencies listed in serverExternalPackages (e.g. ts-deepmerge) are not included in .next/standalone/node_modules. As a consequence:

  • the standalone output is incomplete
  • runtime execution fails with a missing module error, for example:
Error: Cannot find module 'ts-deepmerge'
  • Docker images that rely exclusively on .next/standalone (e.g. distroless images without node_modules installation) cannot start.

Expected behavior Dependencies specified in serverExternalPackages should be:

  • resolved at runtime via .next/standalone/node_modules
  • included in the standalone output, as they were in Next.js ≤ 16.0.x
  • consistently included regardless of whether the build uses Webpack or Turbopack This is the current behavior when running:
next build --webpack

which produces a correct standalone output including ts-deepmerge.

Provide environment information

Operating System:
  Platform: darwin
  Arch: arm64
  Version: Darwin Kernel Version 25.2.0: Tue Nov 18 21:09:34 PST 2025; root:xnu-12377.61.12~1/RELEASE_ARM64_T8112
  Available memory (MB): 8192
  Available CPU cores: 8
Binaries:
  Node: 22.22.0
  npm: 10.9.4
  Yarn: 1.22.22
  pnpm: 10.28.0
Relevant Packages:
  next: 16.1.4 // Latest available version is detected (16.1.4).
  eslint-config-next: N/A
  react: 19.2.3
  react-dom: 19.2.3
  typescript: 5.9.3
Next.js Config:
  output: standalone

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

Runtime, Turbopack

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

next start (local), Other (Deployed)

Additional context

Behavior up to Next.js 16.0.x Up to Next.js 16.0.x, after running next build, the generated .next/standalone folder had the following structure:

.next/
└─ standalone/
   ├─ .next
   ├─ server.js
   ├─ package.json
   ├─ node_modules/
   │  └─.pnpm
   │  └─next
   │  └─react
   │  └─react-dom
   │  └─ts-deepmerge
   │  └─typescript

As expected, ts-deepmerge was correctly included in .next/standalone/node_modules.

Behavior up to Next.js 16.0.x After upgrading to Next.js 16.1.x, ts-deepmerge is no longer present in .next/standalone/node_modules when building with Turbopack.

Workaround If I run the build using Webpack instead:

next build --webpack

The generated .next folder has ts-deepmerge inside .next/standalone/node_modules folder.

Impact on Docker standalone builds This behavior causes a concrete issue when using a Docker setup based on output: "standalone". My Dockerfile follows the recommended multi-stage approach, where the runtime image only copies the contents of .next/standalone and .next/static, without installing node_modules again:

COPY --from=builder /app/.next/standalone ./
COPY --from=builder /app/.next/static ./.next/static

With Next.js 16.1.x + Turbopack, since ts-deepmerge is no longer included in .next/standalone/node_modules, the runtime container fails at startup with a missing dependency error.

Because the final image is based on a distroless Node.js image and does not run pnpm install (by design), there is no way for the missing dependency to be resolved at runtime.

Using next build --webpack restores the previous behavior and produces a correct standalone output, which suggests a regression or behavior change specific to Turbopack in 16.1.x.

I have found a similar issue about this https://github.com/vercel/next.js/issues/87686

extent analysis

TL;DR

The most likely fix is to use the --webpack flag with next build to include dependencies specified in serverExternalPackages in the standalone output.

Guidance

  • The issue seems to be specific to Turbopack in Next.js 16.1.x, as using Webpack resolves the problem.
  • Verify that the serverExternalPackages configuration is correct and that the dependencies are properly installed.
  • Consider using the --webpack flag with next build as a temporary workaround to ensure that dependencies are included in the standalone output.
  • If possible, test the application with a different version of Next.js to see if the issue persists.

Example

No code snippet is provided as the issue seems to be related to the build process and configuration rather than a specific code snippet.

Notes

The issue may be related to a regression or behavior change in Turbopack in Next.js 16.1.x, and using Webpack as a workaround may not be a long-term solution. It's recommended to keep an eye on the similar issue reported on GitHub (https://github.com/vercel/next.js/issues/87686) for any updates or fixes.

Recommendation

Apply the workaround by using the --webpack flag with next build, as it has been confirmed to produce the correct standalone output. This will ensure that dependencies are included in the output until a fix is available for Turbopack.

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