DEV Community

nareshipme
nareshipme

Posted on

When Turbopack Breaks Your Web Worker Builds

In the world of modern frontend development, "speed" is usually a good thing. We want faster hot reloads during development and lightning-fast build times for production.

Recently at ClipCrafter, we hit this wall head-on when upgrading to Next.js 16. While moving towards Turbopack promised us incredible developer experience improvements, it introduced a silent killer: our video processing engine stopped working in production builds because of how Webpack handles worker files differently than Turbo/Turbopack does during the build pipeline.

The Problem: A Broken Worker Pipeline

ClipCrafter relies heavily on @ffmpeg/ffmpeg to handle heavy-duty video manipulation directly in the browser. This requires loading a specific .wasm file and an ESM worker via a Blob URL at runtime.

To make this work, we had configured a custom Webpack loader in next.config.ts. We needed specifically told webpack how to treat these files so they wouldn't be mangled during the bundling process:

// next.config.ts (The "Old" Way that worked)
const nextConfig = {
  webpack: (config, { isServer }) => {
    if (!isServer) {
      // We needed this custom loader to ensure ffmpeg-core 
      // could be resolved correctly via Blob URLs at runtime.
      config.module.rules.push({
        test: /ffmpeg\/dist\/esm\/worker\.js$/,
        loader: 'url-loader', // Or specialized worker loaders
      });
    }
    return config;
  },
};
Enter fullscreen mode Exit fullscreen mode

When we upgraded, Next.js started defaulting to Turbopack for builds in certain environments. Since our configuration was strictly targeting the webpack object and didn't provide a corresponding Turbo-compatible instruction set via turbo: { rules: ... }, those critical worker files were being bundled incorrectly. The result? A production build that looked perfect but crashed with an "Uncaught TypeError" as soon as you tried to initialize any video clip processing.

Moving Toward Hardware Acceleration

While fixing the bundler, we also had a chance to look at our performance bottleneck. We realized ffmpeg.wasm was great for compatibility, but it's essentially running software-based encoding in JavaScript—which is slow and heavy on CPU usage.

We decided to upgrade/integrate with @framewebworker@0.3.0. This library uses WebCodecs, a modern browser API that allows us to tap into the device’s hardware acceleration (H.264). The difference was night and day: we saw encoding speeds jump from "painfully slow" up to 10–50× faster on supported browsers, with an automatic fallback to our existing FFmpeg setup for older devices.

How We Fixed It

To get the build pipeline stable again while embracing these upgrades, we had two main tasks in a single PR:

  1. Force Webpack for Production: Until Next.js provides more robust Turbopack configuration hooks specifically for complex WASM/Worker loaders like ours, we explicitly forced webpack during our production builds to ensure the @ffmpeg/ffmpeg worker remains intact and resolvable at runtime.

  2. Clean up Route Exports: We also had a minor type-safety issue where arbitrary constants (like language lists) were being exported from Next.js App Router files, causing TypeScript violations in generated types during build time. In route.ts, you should only export HTTP handlers (GET, POST) and config objects.

The Lesson Learned

If your application relies on "heavy" browser APIs like WebAssembly (WASM), SharedArrayBuffer, or complex Worker threads: Don't assume the new default bundler just works.

The transition from Webpack to Turbopack is a massive leap forward for dev speed, but it requires you to audit how your most critical pieces of infrastructure—the ones that don't follow standard "UI component" rules—are being bundled. We fixed our build by reverting the production engine back to its proven Webpack configuration while keeping all other Next.js 16 benefits intact.

Have you run into bundling issues with newer versions of Next.js? Let us know in the comments!

Top comments (0)