Skip to content

Move production builds back to Turbopack on Next.js 16.3.1 - #3645

Merged
tom2drum merged 3 commits into
mainfrom
claude/nextjs-version-bump-b89306
Aug 18, 2026
Merged

Move production builds back to Turbopack on Next.js 16.3.1#3645
tom2drum merged 3 commits into
mainfrom
claude/nextjs-version-bump-b89306

Conversation

@tom2drum

Copy link
Copy Markdown
Collaborator

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=dynamic instance in production — the crash that forced next build --webpack in ADR 0001. Verified fixed by building + serving on the rootstock (dynamic) preset: home page renders, Dynamic login modal opens, zero DynamicContextProvider errors.

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)

Metric webpack Turbopack Δ
Bundling time (next build) 186 s 87 s −53%
M1 FCP 2047 ms 1049 ms −49%
M2 first API request 123 ms 55 ms −55%
M5 blocking time 1444 ms 453 ms −69%
M6 JS before FCP 2235 KB gz 2575 KB gz +15%

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

  • package.jsonnext → 16.3.1; drop --webpack from build and build:next.
  • next.config.jsexperimental.useTypeScriptCli: false (required — see gotcha below).
  • pnpm-workspace.yaml — temporary minimumReleaseAge exceptions for next + its @next/env / @next/swc-* internals (16.3.1 is < 1 week old; entries tagged "remove after 20.08.2026").
  • tools/dev-server/prod.preset.sh — default build → Turbopack; --profile stays on webpack.
  • Docs — new ADR 0003; ADR 0001 marked superseded; connect-wallet/CONTEXT.md + AGENTS.md updated.

Kept on webpack deliberately: build:analyze (@next/bundle-analyzer is a webpack plugin) and prod:preset --profile (React react-dom/profiling alias is guaranteed on webpack, undocumented on Turbopack).

Reviewer note — the useTypeScriptCli gotcha

Next 16.3 defaults its build-time type-check to the tsc CLI, which needs a typescript/bin/tsc binary. This repo runs the native TS compiler via the @typescript/typescript6 alias, which ships bin/tsc6 only — so the CLI path aborts the build claiming typescript is missing, on both bundlers (the check runs before bundling). useTypeScriptCli: false switches to the compiler-API path (lib/typescript.js, which the alias does provide); type-checking still runs and passes.

Verification

  • Turbopack prod build on rootstock (dynamic provider): clean, no crash.
  • Webpack build still succeeds (fallback for analyze/profile intact).
  • Docker image build (pnpm build) now uses Turbopack.

🤖 Generated with Claude Code

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 tom2drum left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed 9897b3743b75ffb375add4b7170bd156862f9038895d6bcd01f5c7a6124d8f29838ce0a4534ea55c
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

Comment thread next.config.js
Comment thread src/features/connect-wallet/CONTEXT.md Outdated
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>
@tom2drum
tom2drum merged commit b779051 into main Aug 18, 2026
3 of 10 checks passed
@tom2drum
tom2drum deleted the claude/nextjs-version-bump-b89306 branch August 18, 2026 18:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant