Next.js Turbopack Module Federation in 2026: Sharing Code Across Micro-Frontends Without Webpack A developer working with Next.js micro-frontends found that webpack's Module Federation plugin breaks under Turbopack, since Turbopack does not expose webpack's container format or runtime APIs, causing remote modules to fail at build time with "Cannot find module" errors. The proposed fix reframes module federation as a deployment pattern: Next.js multi-zones share a domain and coordinate routing via rewrites, with shared dependencies resolved at build time through package resolution rather than runtime module containers. The tradeoff is better isolation and independent deployment at the cost of duplicated dependencies and larger JavaScript payloads. This article was written with the assistance of AI, under human supervision and review. Module federation in Next.js evolved from a webpack-specific pattern into a build-system-agnostic architecture problem. Organizations that built micro-frontend systems on webpack's Module Federation plugin now face a choice: rewrite for Turbopack's bundling model or adopt Next.js multi-zones with shared dependencies. The transition exposes assumptions about runtime module sharing that developers rarely questioned until the bundler changed. Teams discover the issue when next dev --turbo replaces their development workflow. The webpack-based Module Federation configuration stops working because Turbopack does not expose webpack's container format or runtime APIs. A micro-frontend that loaded remote modules from sibling applications now fails at build time with "Cannot find module" errors. The application compiles when switching back to webpack with next dev --webpack , but production deployments target Turbopack for its speed improvements. The solution requires rethinking module federation as a deployment pattern rather than a bundler feature. Next.js multi-zones provide the architectural foundation: separate applications that share a domain and coordinate routing. Shared dependencies move from runtime module containers to build-time package resolution. Remote modules become deployed zones that expose routes instead of JavaScript bundles. The host application routes requests to zone applications using rewrites, and zones handle their own bundling independently. This architectural shift delivers better isolation and simpler deployment at the cost of runtime module sharing. Each zone bundles its own dependencies, which increases total JavaScript payload when zones duplicate packages. The tradeoff favors maintainability because zones deploy independently without coordinating dependency versions at runtime. Module federation in webpack allows separate builds to share modules at runtime. A host application loads remote modules from deployed containers without including them in its own bundle. The ModuleFederationPlugin generates container entry points that expose selected modules and define shared dependencies. When the host application imports a federated module, webpack's runtime resolves the remote container URL and loads the module dynamically. Next.js applications use this pattern by configuring webpack in next.config.js . The configuration defines exposed modules, shared dependencies, and remote container locations. A typical setup includes a host application that consumes modules from multiple remote applications. // next.config.js for host application with webpack module federation const { NextFederationPlugin } = require '@module-federation/nextjs-mf' ; module.exports = { webpack config, options { config.plugins.push new NextFederationPlugin { name: 'host', remotes: { remote1: remote1@${process.env.REMOTE1 URL}/ next/static/chunks/remoteEntry.js , remote2: remote2@${process.env.REMOTE2 URL}/ next/static/chunks/remoteEntry.js , }, shared: { react: { singleton: true, requiredVersion: '^18.0.0' }, 'react-dom': { singleton: true, requiredVersion: '^18.0.0' }, }, } ; return config; }, }; The remote applications configure exposed modules that the host can import. Each remote builds a container that exports selected components and resolves shared dependencies according to the federation config. // next.config.js for remote application const { NextFederationPlugin } = require '@module-federation/nextjs-mf' ; module.exports = { webpack config, options { config.plugins.push new NextFederationPlugin { name: 'remote1', filename: 'static/chunks/remoteEntry.js', exposes: { './ProductCard': './components/ProductCard', './CheckoutButton': './components/CheckoutButton', }, shared: { react: { singleton: true }, 'react-dom': { singleton: true }, }, } ; return config; }, }; Runtime module sharing depends on webpack's container format and initialization sequence. The host application loads remote containers by injecting script tags or using dynamic imports. Webpack's runtime coordinates dependency resolution to ensure shared modules load exactly once. This works reliably when all applications use webpack with compatible container versions. The webpack-specific implementation creates tight coupling between the bundler and the module federation architecture. Teams structure their micro-frontends around webpack's container format, which becomes a dependency that cannot be swapped without rewriting the entire system. Module federation architecture diagram showing webpack containers Turbopack replaces webpack as Next.js 16's default bundler. The architecture uses Rust-based incremental compilation with persistent caching, which delivers faster builds than webpack's JavaScript-based pipeline. Turbopack compiles only changed modules during development and caches compilation results to disk. Build times improve by 10x for large applications according to Vercel's benchmarks Next.js 16 release notes, October 2026 . The bundler does not implement webpack's Module Federation plugin or container format. Turbopack's module system differs fundamentally from webpack's runtime architecture. Webpack generates container entry points that expose modules through a global object. Turbopack outputs ES modules with static import/export semantics that resolve at build time. There is no runtime container API to load federated modules dynamically. Next.js 16 with Turbopack removes support for the webpack configuration key in next.config.js . Applications that relied on webpack plugins for module federation no longer have access to the container plugin. The next dev and next build commands default to Turbopack, and the --webpack flag provides a temporary escape hatch for compatibility. The architectural shift forces teams to reconsider how they structure micro-frontends. Runtime module federation assumed a bundler would coordinate module loading across deployed applications. Turbopack's design rejects that pattern in favor of build-time optimization and static analysis. Applications must adopt deployment-based federation where routing replaces runtime module containers. Turbopack supports webpack loaders through a compatibility layer in the turbopack.rules configuration Next.js Turbopack API reference, v16.1 . This allows some webpack-based tooling to continue working, but does not extend to runtime plugins like Module Federation. The loader compatibility targets file transformations during compilation, not runtime module resolution. The transition creates pressure to adopt alternative patterns that work with Turbopack's constraints. Next.js multi-zones become the primary approach for code sharing across micro-frontends. Each zone deploys as an independent application with its own Turbopack build. Zones coordinate through routing rather than module containers. Multi-zones in Next.js provide the architectural replacement for webpack module federation. Each zone is a separate Next.js application that serves a subset of routes on a shared domain. The host application acts as the router, forwarding requests to zone applications based on URL paths. Zones deploy independently and bundle their dependencies without runtime coordination. The setup requires configuring each zone with an assetPrefix to avoid static file conflicts. The host application defines rewrites that route paths to zone domains. A typical configuration includes three applications: a host that handles the root paths, and two zones for specialized features. python // next.config.ts for a zone application e.g., product catalog import type { NextConfig } from 'next'; const config: NextConfig = { assetPrefix: '/catalog-static', async rewrites { return { beforeFiles: { source: '/catalog-static/ next/:path+', destination: '/ next/:path+', }, , }; }, }; export default config; The host application configures rewrites to forward zone paths to their deployed domains. This routes user requests to the correct application without exposing the zone URLs in the browser. python // next.config.ts for host application import type { NextConfig } from 'next'; const config: NextConfig = { async rewrites { return { source: '/catalog', destination: ${process.env.CATALOG ZONE URL}/catalog , }, { source: '/catalog/:path+', destination: ${process.env.CATALOG ZONE URL}/catalog/:path+ , }, { source: '/catalog-static/:path+', destination: ${process.env.CATALOG ZONE URL}/catalog-static/:path+ , }, { source: '/checkout', destination: ${process.env.CHECKOUT ZONE URL}/checkout , }, { source: '/checkout/:path+', destination: ${process.env.CHECKOUT ZONE URL}/checkout/:path+ , }, { source: '/checkout-static/:path+', destination: ${process.env.CHECKOUT ZONE URL}/checkout-static/:path+ , }, ; }, }; export default config; Shared code moves from runtime module federation to build-time package references. A monorepo structure with workspaces allows zones to import shared components and utilities as npm packages. Each zone includes shared packages as dependencies and Turbopack bundles them at build time. // package.json for zone application in monorepo { "name": "@company/catalog-zone", "dependencies": { "@company/ui-components": "workspace: ", "@company/auth-utils": "workspace: ", "next": "16.1.0", "react": "^18.3.1", "react-dom": "^18.3.1" } } Zones import shared components using standard ES module imports. Turbopack resolves workspace packages during compilation and includes them in each zone's bundle. js // app/catalog/page.tsx in catalog zone import { ProductCard } from '@company/ui-components'; import { useAuth } from '@company/auth-utils'; export default function CatalogPage { const { user } = useAuth ; return