Move production builds back to Turbopack on Next.js 16.3.1 - #3645
Merged
Conversation
Bump Next.js 16.2.6 -> 16.3.1, which fixes the Turbopack scope-hoisting bug that miscompiles the Dynamic-labs SDK and hard-crashed every page of any dynamic-auth instance in production. That crash was the whole reason ADR 0001 forced `next build --webpack`; verified fixed on the rootstock (dynamic) preset. Production builds now use Turbopack (the Next default), which on 16.3.1 is both ~2x faster to bundle and faster at runtime (median FCP 2047ms -> 1049ms, blocking 1444ms -> 453ms), at the cost of ~15% more JS before FCP that no longer hurts load. Full A/B in ADR 0003. - package.json: next -> 16.3.1; drop --webpack from `build` / `build:next` - next.config.js: experimental.useTypeScriptCli = false. Next 16.3 defaults the build type-check to the tsc CLI, which needs typescript/bin/tsc; this repo's native-TS alias (@typescript/typescript6) ships bin/tsc6 only, so the CLI path aborts the build claiming typescript is missing. The compiler-API path uses lib/typescript.js, which the alias provides. - pnpm-workspace.yaml: temporary minimumReleaseAge exceptions for next and its @next/env + @next/swc-* internals (16.3.1 is under the 1-week gate) - tools/dev-server/prod.preset.sh: default build -> Turbopack; --profile stays on webpack (react-dom/profiling alias is webpack-only) - build:analyze stays on webpack (@next/bundle-analyzer is a webpack plugin) - docs: new ADR 0003; ADR 0001 marked superseded; connect-wallet CONTEXT and AGENTS.md updated Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Turbopack's `output: standalone` tracer copies only @swc/helpers/cjs and drops the esm/ entry points that Next's require-hook loads at runtime, so the shipped image's `node server.js` crashed on boot with `Cannot find module '@swc/helpers/esm/_interop_require_default.js'`. webpack traced the package fully, so this only surfaced after the bundler switch — and only on the standalone path, not under `next start`, so it slipped past local checks until a review-env deploy crashlooped the frontend pod. `outputFileTracingIncludes` force-includes the whole package until the Turbopack tracer is fixed upstream. Verified: `node .next/standalone/server.js` now boots and serves 200. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
tom2drum
commented
Aug 18, 2026
tom2drum
left a comment
Collaborator
Author
There was a problem hiding this comment.
| Reviewed | 9897b3743b75ffb375add4b7170bd156862f9038 → 895d6bcd01f5c7a6124d8f29838ce0a4534ea55c |
| Round | 1 of 3 |
| Findings | 1 blocker · 1 major · 1 nit |
| By axis | Spec 0 (no task spec) · Standards 1 · Correctness 2 |
| Outcome | blocked |
Not anchorable
major · Correctness — .agents/tasks/3566-main-page-loading-perf/tools/README.md:62-63
Claim. ``prod:preset builds with the same bundler as the shipped image (webpack, per that ADR) — this change switched both to Turbopack; the README still points at ADR 0001 and will mislead anyone re-running the perf tools.
Suggested fix. Point at ADR 0003 and say Turbopack; drop the webpack claim.
— Reviewed by Cursor Grok 4.5
The dynamic-mode verify rule restated the Turbopack crash detail already owned by ADR 0003. Keep the "verify in a production build" rule and the ADR pointer; drop the restatement. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What & why
Bumps Next.js 16.2.6 → 16.3.1 and switches production builds from webpack back to Turbopack (the Next default).
Next 16.3.1 fixes the Turbopack scope-hoisting bug that miscompiled the Dynamic-labs SDK and hard-crashed every page of any
NEXT_PUBLIC_ACCOUNT_AUTH_PROVIDER=dynamicinstance in production — the crash that forcednext build --webpackin ADR 0001. Verified fixed by building + serving on therootstock(dynamic) preset: home page renders, Dynamic login modal opens, zeroDynamicContextProvidererrors.The main motivation is CI build time. On 16.3.1 the old webpack-vs-Turbopack trade-off is gone — Turbopack is faster to build and faster at runtime.
Perf A/B (rootstock, medians of 3 headless runs, same machine — within-method deltas only)
next build)Turbopack ships ~15% more JS before FCP but halves FCP and cuts blocking time ~2/3 — the cost that used to live in execution is gone. Rationale + full context in the new ADR 0003.
Changes
next→ 16.3.1; drop--webpackfrombuildandbuild:next.experimental.useTypeScriptCli: false(required — see gotcha below).minimumReleaseAgeexceptions fornext+ its@next/env/@next/swc-*internals (16.3.1 is < 1 week old; entries tagged "remove after 20.08.2026").--profilestays on webpack.connect-wallet/CONTEXT.md+AGENTS.mdupdated.Kept on webpack deliberately:
build:analyze(@next/bundle-analyzeris a webpack plugin) andprod:preset --profile(Reactreact-dom/profilingalias is guaranteed on webpack, undocumented on Turbopack).Reviewer note — the
useTypeScriptCligotchaNext 16.3 defaults its build-time type-check to the
tscCLI, which needs atypescript/bin/tscbinary. This repo runs the native TS compiler via the@typescript/typescript6alias, which shipsbin/tsc6only — so the CLI path aborts the build claimingtypescriptis missing, on both bundlers (the check runs before bundling).useTypeScriptCli: falseswitches to the compiler-API path (lib/typescript.js, which the alias does provide); type-checking still runs and passes.Verification
pnpm build) now uses Turbopack.🤖 Generated with Claude Code