← the writing notes 9 min

Turbopack in 2026: Where the Build Time Actually Goes

Turbopack promised to kill slow builds. And honestly, for dev mode it largely delivered. But production builds still bleed time in ways most developers never bother to trace. Here's where it actually goes.

Amber-lit server room corridor with blinking rack lights, shot on 35mm film with shallow depth of field

Three years ago I was sitting on a call with a client in Toronto, watching a Next.js build crawl through 94 seconds while we both pretended to be fine with it. Webpack. Eight thousand modules. A monorepo with shared UI components that nobody had audited since 2021. The client asked if we could "make it faster." I quoted two days of work. It took four. And even then we knocked it down to 61 seconds, which felt like winning a race nobody wanted to be in.

Turbopack changed that story. Mostly. But here in 2026, I keep seeing developers assume that switching to Turbopack is a finish line rather than a starting point. They flip the flag, shave 40% off their dev server startup, and call it done. The actual bottlenecks just moved somewhere quieter.

So let me walk you through where build time really goes when you're running Turbopack in a real production codebase. Not a todo app. Not the Next.js example template. A real site with 200+ routes, a CMS integration, and a client who notices every second.

The Gap Between Dev Mode and Production Builds

Here's the thing most people miss: Turbopack's biggest wins are in the dev server. Incremental compilation, module-level caching, the whole Rust-powered graph. In dev mode, it's genuinely transformative. I clocked a cold start on a Seahawk client project going from 28 seconds under webpack to under 4 with Turbopack. That's not a rounding error.

But next build is a different animal. As of early 2026, Turbopack's production build support is stable but it doesn't rewrite the entire pipeline. Static analysis, page optimisation, and the SWC compiler are all still doing heavy lifting alongside Turbopack's bundler. You're not getting a uniform 10x on production output.

This matters because developers benchmark the wrong thing. They watch next dev spin up and conclude the build is fast. Then CI takes 3 minutes and they shrug.

What the Turbopack Architecture Actually Does

Turbopack operates on a demand-driven computation model. It builds only what's requested, caches at the module level, and invalidates precisely rather than broadly. This is why the Vercel team's architecture writeup talks about "function-level memoisation." It's not marketing copy. It's the real mechanism behind why touching one component doesn't force a full re-bundle.

The implication: your fastest gains happen where invalidation was previously too broad. Shared utility files, large barrel exports, deeply nested re-exports. Those are the places Webpack was punishing you silently.

Where Time Actually Disappears in 2026

I audited four codebases last quarter using NEXT_TURBOPACK_TRACING=1. Yes, that env variable exists and yes, it spits out a trace file you can load into Chrome's performance panel. Highly recommend it before assuming any particular thing is the culprit.

Here's what I found, ranked roughly by how often they show up:

  1. Barrel file explosions. A single index.ts re-exporting 60 components from a design system pulls every one of those modules into the graph even if you use two. Turbopack handles this better than Webpack but it doesn't make the problem vanish. The fix is granular imports. Always.
  2. Type-checking not separated from bundling. Running tsc --noEmit inside the same build pipeline that Turbopack is processing is doubling your wall time. Split them. TypeScript type checking and Turbopack bundling should be parallel jobs in CI, not sequential steps.
  3. Unstable module IDs in third-party packages. Some npm packages still ship CommonJS with dynamic requires. Turbopack has to fall back to slower analysis paths for these. I hit this last month with an older version of a PDF generation library. Upgraded it, saved 8 seconds.
  4. Image optimisation at build time. If you're pre-generating thousands of image variants with next/image and a static export, that's synchronous and CPU-bound. It's not Turbopack. But it shows up in the build trace and people blame the bundler.
  5. Large `getStaticProps` data payloads. Fetching 4MB of CMS data per page during build, across 300 pages, is a network and parsing problem. Again, not Turbopack. But it sits inside the same 180-second build and gets blamed collectively.

The uncomfortable truth is that Turbopack accelerated the bundling phase so much that everything around it now looks slow by comparison. It's like upgrading your kitchen bin to open automatically and then realising the walk to the wheelie bin outside is the actual inconvenience.

The Barrel File Problem Deserves Its Own Section

I cannot stress this enough. Barrel files are the single most common self-inflicted build wound I see across agencies.

A client came to us in late 2025 with a component library that had this structure:

`` components/ index.ts (exports 140 named components) ``

Every page importing even one button pulled the entire 140-component graph. With Webpack, tree-shaking partially helped at output time. With Turbopack, the module graph still had to be traversed and understood before anything could be pruned. The dev server wasn't slow per se, but cold starts were painful.

We restructured to path-specific imports:

`` import { Button } from '@company/ui/button' import { Modal } from '@company/ui/modal' ``

Cold dev start dropped from 11 seconds to under 3. Production build dropped by 22 seconds. Nobody touched Turbopack config. The fix was just... not being lazy about imports.

There's actually a good eslint-plugin-import rule for catching these: import/no-barrel-files. Add it to your lint config and treat violations as build debt.

Caching in CI: You're Probably Leaving 40 Seconds on the Table

Turbopack's local caching is excellent. CI caching is a separate problem and most teams set it up once and never revisit it.

The Turbopack cache lives in .next/cache/turbopack by default. If your CI pipeline (GitHub Actions, CircleCI, whatever) isn't persisting that directory between runs, you're doing a full cold build every single time. On a codebase of any reasonable size, that's 30 to 60 seconds of pure waste per run.

Here's what a proper cache key looks like for a Next.js + Turbopack setup in GitHub Actions:

  • Cache key: hash of package-lock.json + hash of next.config.js + hash of tsconfig.json
  • Cache path: .next/cache
  • Restore keys: fallback to previous cache on the same branch, then main

That's it. Most teams only hash package-lock.json . But if your next.config.js changes the Turbopack config (experimental features, module aliases, custom loaders), you want that invalidated. I've seen bugs where a stale cache was serving incorrect module resolutions after a config change. Nasty to debug at 11pm.

Seahawk had a fintech project where just fixing the cache key structure knocked the average CI build from 4 minutes 20 seconds to 2 minutes 50 seconds. Same code. Same hardware. Just smarter cache invalidation.

Custom Loaders and Why They're Killing Your Gains

Turbopack supports custom loaders, but there's a cost. Every custom loader drops you out of Turbopack's native fast path and into a compatibility layer. The Vercel team is pretty honest about this in the Next.js Turbopack configuration docs.

I see this most often with:

  • SVG loaders (people converting SVGs to React components at build time)
  • MDX with heavy remark/rehype plugin chains
  • CSS Modules with custom PostCSS configs that include rarely-used plugins

For SVGs specifically, the move in 2026 is to pre-compile your icon library to React components as a separate build step, not at Next.js build time. SVGR is excellent for this as a standalone script. Run it when your design tokens change, commit the output, and let Turbopack treat them as regular .tsx files.

MDX is trickier. If you're running 40 remark plugins, you're going to feel it. Audit which ones you actually need. I've seen codebases running remark-gfm , remark-smartypants, a custom footnotes plugin, and two others, where only two of those were producing visible output differences. Cut the unused ones.

The Module Resolution Tax Nobody Talks About

Path aliases. Everyone uses them. @/components , @/lib , ~/utils. They're convenient. They're also a small tax that compounds.

Turbopack resolves aliases on every import encounter. In a large codebase with 4,000 imports and 12 aliases configured, that's 48,000 resolution operations per build. Not catastrophic. But not free either.

The fix isn't to remove aliases. It's to be precise with them. Avoid wildcard alias patterns where a specific path will do. And keep your tsconfig.json paths in sync with your next.config.js turbopack resolveAlias config. Drift between these two causes Turbopack to do redundant resolution work. I've seen 4-5 second savings just from cleaning this up.

What 2026 Turbopack Still Doesn't Do

Look, I like Turbopack. We use it on most new Seahawk projects. But honesty matters.

  • Bundle analysis isn't as mature as Webpack's ecosystem. @next/bundle-analyzer works but the visualisation is less granular than what you'd get from webpack-bundle-analyzer. This is improving but it's not there yet.
  • Plugin ecosystem is smaller. If your stack relies on heavily customised Webpack plugins (some legacy enterprise setups do), migration is still a real project, not an afternoon.
  • Windows performance has historically lagged behind macOS and Linux. This is getting better with each Next.js release, but if your team is Windows-heavy, benchmark before you commit.

None of these are dealbreakers. But they're real considerations if you're evaluating whether to migrate an existing project versus starting fresh.

How to Actually Trace Your Build

Stop guessing. Run this:

  1. Set NEXT_TURBOPACK_TRACING=1 in your environment
  2. Run next build (or next dev if you're profiling dev startup)
  3. Open .next/trace in Perfetto UI or Chrome's chrome://tracing
  4. Filter by duration. Anything over 2 seconds in a single module is worth investigating.

This is the same approach I use before any build optimisation engagement. The trace tells you where the time goes. Everything else is guesswork dressed up as expertise.

---

FAQ

Is Turbopack stable enough for production builds in 2026?

Yes, production build support landed as stable in late 2024 and has matured significantly through 2025. For most Next.js projects starting fresh, I'd default to Turbopack without hesitation. For legacy projects with heavy Webpack customisation, do a spike first and measure.

Does Turbopack replace SWC?

No. SWC is the TypeScript and JSX transpiler. Turbopack is the bundler. They work together. Turbopack uses SWC under the hood for transformation. You don't choose between them.

Why is my Turbopack dev server fast but CI build still slow?

Almost certainly one of these: type-checking running serially with bundling, no CI cache configured for .next/cache, or image optimisation dominating the static generation phase. Run the trace. It'll show you which one.

Should I switch an existing Webpack project to Turbopack right now?

If it's a greenfield or low-customisation project, yes. If you have 15 custom Webpack plugins and a complex loader chain, budget a proper migration sprint. Don't do it as an afterthought on a Friday afternoon. (I say this from personal experience. Don't ask about the Friday.)

Does Turbopack work with Nx or Turborepo monorepos?

Yes, and actually quite well. Turborepo caching stacks nicely on top of Turbopack's internal caching, and the two tools share lineage from the same team. The combination is genuinely good for large monorepos where only a subset of packages change per PR.

---

Build tooling is boring until your CI bill is $800 a month and your dev team is complaining about cold starts at standup. Turbopack moved the bottleneck, which is progress. But it didn't eliminate the need to think clearly about where time goes. Trace first. Optimise second. And for the love of everything, fix your barrel files.

Need this done, not just read?

start a project book 30 minutes