Vinext’s build pipeline transforms your Next.js application into production-ready bundles for deployment. This guide covers the build process, optimization strategies, and deployment preparation.
Vinext uses a conservative code-splitting strategy optimized for real-world performance:From packages/vinext/src/index.ts:
function clientManualChunks(id: string): string | undefined { // React framework — always loaded, shared across all pages. // Isolating React into its own chunk is the single highest-value // split: it's ~130KB compressed, loaded on every page, and its // content hash rarely changes between deploys. if (id.includes("node_modules")) { const pkg = getPackageName(id); if (!pkg) return undefined; if ( pkg === "react" || pkg === "react-dom" || pkg === "scheduler" ) { return "framework"; } // Let Rollup handle all other vendor code via its default // graph-based splitting. This produces a reasonable number of // shared chunks (typically 5-15) based on actual import patterns, // with good compression efficiency. return undefined; } // Vinext shims — small runtime, shared across all pages. if (id.startsWith(shimsDir)) { return "vinext"; } return undefined;}
Vinext uses aggressive treeshaking to eliminate unused exports from vendor packages:
const clientTreeshakeConfig = { preset: "recommended" as const, moduleSideEffects: "no-external" as const,};
moduleSideEffects: "no-external" means:
Local project modules: preserve side effects (CSS imports, polyfills)
node_modules packages: treat as side-effect-free unless exports are used
This is the single highest-impact optimization for large barrel-exporting libraries:Example: mermaid
Without this setting, importing one diagram type includes all 15+ diagram renderers (~400KB). With "no-external", only the used renderer is included (~50KB).Example: @mui/material
Importing Button from the barrel doesn’t pull in the entire library (80+ components). Only Button and its dependencies are included.
Vinext computes which chunks are lazy-loaded (behind React.lazy(), next/dynamic, or manual import()) and excludes them from preload hints:
function computeLazyChunks( buildManifest: Record<string, ManifestChunk>): string[] { // Collect all chunk files statically reachable from entries const eagerFiles = new Set<string>(); const visited = new Set<string>(); const queue: string[] = []; // Start BFS from all entry chunks for (const key of Object.keys(buildManifest)) { const chunk = buildManifest[key]; if (chunk.isEntry) { queue.push(key); } } while (queue.length > 0) { const key = queue.shift()!; if (visited.has(key)) continue; visited.add(key); const chunk = buildManifest[key]; if (!chunk) continue; eagerFiles.add(chunk.file); // Mark CSS as eager (avoid FOUC) if (chunk.css) { for (const cssFile of chunk.css) { eagerFiles.add(cssFile); } } // Follow only static imports — NOT dynamicImports if (chunk.imports) { for (const imp of chunk.imports) { if (!visited.has(imp)) { queue.push(imp); } } } } // Any JS file NOT in eagerFiles is a lazy chunk const lazyChunks: string[] = []; for (const key of Object.keys(buildManifest)) { const chunk = buildManifest[key]; if (chunk.file && !eagerFiles.has(chunk.file) && chunk.file.endsWith(".js")) { lazyChunks.push(chunk.file); } } return lazyChunks;}
Lazy chunks are stored in __VINEXT_LAZY_CHUNKS__ and excluded from <link rel="modulepreload"> and <script type="module"> tags. They’re fetched on demand when the dynamic import executes.
Native Node.js modules (sharp, resvg, satori) are auto-stubbed for Workers:
const NATIVE_MODULES = [ "sharp", "@resvg/resvg-js", "@napi-rs/canvas", "lightningcss",];for (const mod of NATIVE_MODULES) { config.resolve.alias[mod] = "vinext/stubs/native-module";}
The stub throws a descriptive error if the module is accessed at runtime:
// vinext/stubs/native-module.tsexport default new Proxy({}, { get(target, prop) { throw new Error( `Native module accessed at runtime. This module requires Node.js ` + `native bindings and cannot run on Cloudflare Workers. ` + `To fix: either avoid using this module or implement a pure-JS alternative.` ); },});