Turbopack Chunking: Fewer Requests or Less Code

On September 3, 2026, the Turbopack team at Vercel published How Turbopack chunks your JavaScript — a walkthrough of how the bundler decides which module lands in which file, and why there is no single correct split. More usefully, it exposes the cost model that has been running quietly inside every build, and Next.js 16.3 now lets you tune it.

The problem: two goals in conflict

The simplest strategy is one chunk for the whole app. One network request, and every visit after the first is a cache hit. The cost is that a page needing almost no JavaScript still downloads the code for every other page, and that weight grows with the project.

Flip it and you get one chunk per page. Nothing is over-shipped, but a shared component like <Footer /> ends up inside every page's chunk. A visitor who opens four pages downloads that footer four times.

Go finer still — one chunk per module — and duplication disappears, replaced by hundreds of tiny requests. HTTP/2 made requests cheaper, not free, and compression works worse across many small files because gzip cannot find repeated patterns beyond a single file boundary.

What changed: merging as a probability bet

Turbopack's answer is to merge small chunks into larger ones, but only within a chunk group — the set of chunks that load together for one route. Merging inside a group is safe by construction: it can't add anything the page wasn't already downloading.

The harder question is when merging pays off, and the answer is statistical. Considering a merge of chunk A with chunk B, Turbopack counts how many chunk groups use only A, only B, and both, then weighs benefit against cost. Merging always wins if the visitor loads one page and leaves. Across a navigation it only wins when the second page needs both chunks; otherwise the merged file is useless there and A gets downloaded twice. To weight those two worlds, the algorithm assumes two-thirds of sessions are a single page.

Numbers the team measured on a real eight-step session through nextjs.org:

| Strategy | Code downloaded | Requests | | --- | --- | --- | | No merging | 561.6 KiB | 96 | | Turbopack defaults | 554.8 KiB | 38 | | One chunk per group | 610.0 KiB | 15 |

Defaults cut requests by more than half while shipping slightly less code. Maximum merging cut requests further but shipped about 10% more code across the session.

The model is now configurable

Two things limited the algorithm: merging is decided at build time, before anyone visits, and it has to guess how people move through your site. Next.js 16.3 attacks both.

next.config.ts
import type { NextConfig } from 'next'

const nextConfig = {
  experimental: {
    turbopackChunking: {
      // emit un-merged variants alongside merged chunks
      generateComponentChunks: true,
      minComponentChunkSize: 20000,
      // defaults to 0.67 — your bounce rate is a good estimate
      firstPageLoadPriority: 0.5,
      // routes visitors usually land on first
      priorityRoutes: [/^\/$/, /^\/pricing/],
      minChunkSize: 50000,
      maxChunkCountPerGroup: 40,
    },
    turbopackCjsTreeShaking: true,
    turbopackSharedRuntime: true,
  },
} satisfies NextConfig

export default nextConfig

generateComponentChunks is the sharpest idea here. Every merged chunk also emits its constituent component chunks, so at request time the runtime picks whichever is cheaper: the merged file, or only the pieces the browser is missing. It works in reverse too — a chunk already loaded as part of a merged file is never re-fetched on its own.

firstPageLoadPriority and priorityRoutes replace a global guess with your site's actual shape. High bounce rate argues for a fast first load; heavy navigation argues the opposite. The announcement also describes clusters, groups of routes commonly visited together.

Alongside them, turbopackSharedRuntime replaces per-page runtime chunks with one shared runtime, saving a blocking request and roughly 10 KB of client JavaScript on every navigation after the first. turbopackCjsTreeShaking extends dead-code elimination to CJS modules, which previously shipped unused imports straight to the browser.

Real-world caveats

These flags are experimental, and the Next.js docs say plainly they are not recommended for production yet. The size thresholds are measured in bytes of uncompressed, unminified code — roughly five times the shipped output — so a minChunkSize of 50000 is not a 50 KB file. And the nextjs.org table is not your table: a documentation site where people click around benefits from less merging; a single landing page benefits from the opposite. Measure the session you actually care about, change one value, measure again.

Takeaway

Chunking is not a bundler implementation detail. It is a bet on how your visitors behave, and until now that bet was made for you at build time with generic assumptions. Next.js 16.3 lets you replace the assumption with your own analytics, and hands part of the decision to the runtime, where the real cache state is known.

Primary source: How Turbopack chunks your JavaScript. For context on the faster build tooling in the same release, see TypeScript 7: A Native Compiler, 10× Faster.

Turbopack Chunking: Fewer Requests or Less Code · bahashwan.dev