From e0ee0f3ae7a3b65585357b59e04af6b28c85b9ce Mon Sep 17 00:00:00 2001 From: Luke Sandberg Date: Thu, 2 Oct 2025 12:08:47 -0700 Subject: [PATCH 1/3] auto select turbopack for custom servers as well --- packages/next/errors.json | 3 ++- packages/next/src/server/next.ts | 27 +++++++++++++++++++++------ 2 files changed, 23 insertions(+), 7 deletions(-) diff --git a/packages/next/errors.json b/packages/next/errors.json index 6da4b883bac3d..8f021d638875f 100644 --- a/packages/next/errors.json +++ b/packages/next/errors.json @@ -848,5 +848,6 @@ "847": "Route %s with \\`dynamic = \"error\"\\` couldn't be rendered statically because it used \\`connection()\\`. See more info here: https://nextjs.org/docs/app/building-your-application/rendering/static-and-dynamic#dynamic-rendering", "848": "%sused %s. \\`searchParams\\` is a Promise and must be unwrapped with \\`await\\` or \\`React.use()\\` before accessing its properties. Learn more: https://nextjs.org/docs/messages/sync-dynamic-apis", "849": "Route %s with \\`dynamic = \"error\"\\` couldn't be rendered statically because it used \\`cookies()\\`. See more info here: https://nextjs.org/docs/app/building-your-application/rendering/static-and-dynamic#dynamic-rendering", - "850": "metadataBase is not a valid URL: %s" + "850": "metadataBase is not a valid URL: %s", + "851": "Pass either `webpack` or `turbopack`, not both." } diff --git a/packages/next/src/server/next.ts b/packages/next/src/server/next.ts index 2ca7d7b9bffb9..a59ea728a92b1 100644 --- a/packages/next/src/server/next.ts +++ b/packages/next/src/server/next.ts @@ -534,15 +534,30 @@ function createServer( options: NextServerOptions & { turbo?: boolean turbopack?: boolean + webpack?: boolean } ): NextWrapperServer { - if ( - options && - (options.turbo || options.turbopack || process.env.IS_TURBOPACK_TEST) - ) { - // Configure TURBOPACK if it isn't already set - process.env.TURBOPACK ??= '1' + // next sets customServer to false when calling this function, in that case we don't want to modify the environment variables + if (options?.customServer !== false) { + const selectTurbopack = + options && + (options.turbo || options.turbopack || process.env.IS_TURBOPACK_TEST) + const selectWebpack = + options && (options.webpack || process.env.IS_WEBPACK_TEST) + if (selectTurbopack && selectWebpack) { + throw new Error('Pass either `webpack` or `turbopack`, not both.') + } + if (selectTurbopack || !selectWebpack) { + process.env.TURBOPACK ??= selectTurbopack ? '1' : 'auto' + } + } else { + if (options && (options.webpack || options.turbo || options.turbopack)) { + throw new Error( + 'Only custom servers can pass `webpack`, `turbo`, or `turbopack`.' + ) + } } + // The package is used as a TypeScript plugin. if ( options && From 80c2e6da93cc651e72edac2dacca8224f67ce513 Mon Sep 17 00:00:00 2001 From: Luke Sandberg Date: Thu, 2 Oct 2025 12:11:53 -0700 Subject: [PATCH 2/3] fix a missing error --- packages/next/errors.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/next/errors.json b/packages/next/errors.json index 8f021d638875f..cd3f62c8209f2 100644 --- a/packages/next/errors.json +++ b/packages/next/errors.json @@ -849,5 +849,6 @@ "848": "%sused %s. \\`searchParams\\` is a Promise and must be unwrapped with \\`await\\` or \\`React.use()\\` before accessing its properties. Learn more: https://nextjs.org/docs/messages/sync-dynamic-apis", "849": "Route %s with \\`dynamic = \"error\"\\` couldn't be rendered statically because it used \\`cookies()\\`. See more info here: https://nextjs.org/docs/app/building-your-application/rendering/static-and-dynamic#dynamic-rendering", "850": "metadataBase is not a valid URL: %s", - "851": "Pass either `webpack` or `turbopack`, not both." + "851": "Pass either `webpack` or `turbopack`, not both.", + "852": "Only custom servers can pass `webpack`, `turbo`, or `turbopack`." } From 129e9835954e6cdc378e53740b2bb41a49d77857 Mon Sep 17 00:00:00 2001 From: Luke Sandberg Date: Thu, 2 Oct 2025 14:31:54 -0700 Subject: [PATCH 3/3] deprecate the turbo option --- packages/next/src/server/next.ts | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/packages/next/src/server/next.ts b/packages/next/src/server/next.ts index a59ea728a92b1..9f479bc0996f3 100644 --- a/packages/next/src/server/next.ts +++ b/packages/next/src/server/next.ts @@ -52,6 +52,15 @@ export type NextServerOptions = Omit< > & Partial> +export type NextBundlerOptions = { + /** @deprecated Use `turbopack` instead */ + turbo?: boolean + /** Selects Turbopack as the bundler */ + turbopack?: boolean + /** Selects Webpack as the bundler */ + webpack?: boolean +} + export type RequestHandler = ( req: IncomingMessage, res: ServerResponse, @@ -531,14 +540,11 @@ class NextCustomServer implements NextWrapperServer { // This file is used for when users run `require('next')` function createServer( - options: NextServerOptions & { - turbo?: boolean - turbopack?: boolean - webpack?: boolean - } + options: NextServerOptions & NextBundlerOptions ): NextWrapperServer { // next sets customServer to false when calling this function, in that case we don't want to modify the environment variables - if (options?.customServer !== false) { + const isCustomServer = options?.customServer ?? true + if (isCustomServer) { const selectTurbopack = options && (options.turbo || options.turbopack || process.env.IS_TURBOPACK_TEST)