Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/cloudflare/vinext/llms.txt

Use this file to discover all available pages before exploring further.

Builds your Next.js application for production. Automatically detects whether you’re using App Router or Pages Router and runs the appropriate build pipeline.

Usage

vinext build [options]

Options

--help
flag
Show help for this command. Can also use -h.
vinext build --help

Behavior

Router Detection

vinext automatically detects your router type and runs the appropriate build:
# Detects app/ or src/app/
vinext build

# Output:
#   vinext build  (Vite 6.0.0)
#
#   Building for production...
#   ✓ Built RSC environment
#   ✓ Built SSR environment
#   ✓ Built client environment
#
#   Build complete. Run `vinext start` to start the production server.

App Router Build Process

For App Router projects, vinext uses createBuilder() to run a multi-environment build:
// From cli.ts:220-224
const builder = await vite.createBuilder(config);
await builder.buildApp();
This creates three separate builds:
  1. RSC Environment (dist/server/index.js)
    • React Server Components runtime
    • Server-side route handlers
    • Server Actions
  2. SSR Environment (dist/server/ssr/index.js)
    • Server-side rendering for Client Components
    • Imported by RSC entry at runtime
  3. Client Environment (dist/client/)
    • Hydration scripts
    • Client Component bundles
    • Static assets (CSS, images, fonts)

Pages Router Build Process

For Pages Router projects, vinext runs two builds:
// From cli.ts:229-258
// 1. Client build
await vite.build({
  root: appRoot,
  plugins: [vinext()],
  build: {
    outDir: "dist/client",
    manifest: true,
    ssrManifest: true,
    rollupOptions: {
      input: "virtual:vinext-client-entry",
      output: clientOutputConfig,
      treeshake: clientTreeshakeConfig,
    },
  },
});

// 2. Server build
await vite.build({
  root: appRoot,
  plugins: [vinext()],
  build: {
    outDir: "dist/server",
    ssr: "virtual:vinext-server-entry",
    rollupOptions: {
      output: {
        entryFileNames: "entry.js",
      },
    },
  },
});
This creates:
  1. Client Build (dist/client/)
    • Bundled JavaScript (code-split by route)
    • CSS files (extracted and minified)
    • Static assets
    • .vite/manifest.json and .vite/ssr-manifest.json
  2. Server Build (dist/server/entry.js)
    • SSR entry point
    • API route handlers
    • Server-side rendering logic

Build Output

Directory Structure

dist/
├── client/
   ├── assets/          # JS/CSS bundles
   ├── index-a1b2c3.js
   └── style-d4e5f6.css
   ├── _next/           # Next.js assets
   └── .vite/           # Vite manifests
├── server/
   ├── index.js         # RSC entry
   └── ssr/
       └── index.js     # SSR entry

Build Artifacts

  • JavaScript bundles: Code-split by route and lazy-loaded
  • CSS files: Extracted, minified, and automatically injected
  • Images/fonts: Copied to dist/client/ with hashed filenames
  • Manifest files: Used by SSR to map modules to assets
  • RSC handler (App Router): Renders React Server Components to RSC stream
  • SSR handler (Pages Router): Renders pages to HTML on request
  • API routes: Bundled into server entry
  • Server Actions (App Router): Bundled with RSC entry
  • manifest.json: Maps module IDs to built asset paths
  • ssr-manifest.json: Maps Client Component imports to asset URLs for preloading

Build Optimizations

vinext applies these optimizations automatically:

Code Splitting

Each page/route gets its own bundle:
# Pages Router example
dist/client/assets/
  index-a1b2c3.js      # Home page
  about-b2c3d4.js      # About page
  contact-c3d4e5.js    # Contact page
Shared code is extracted into separate chunks:
  vendor-d4e5f6.js     # node_modules code
  shared-e5f6a7.js     # Shared page code

Tree Shaking

Unused code is eliminated at build time:
// From cli.ts:240
treeshake: clientTreeshakeConfig,
Only code that’s actually imported and used is included in the bundle.

Minification

All JavaScript and CSS is minified:
  • JavaScript: Minified with esbuild (fast and effective)
  • CSS: Minified with cssnano
  • HTML: Inline scripts/styles are minified

Asset Hashing

All assets get content-based hashes for optimal caching:
index-a1b2c3.js   # Hash: a1b2c3 (changes when content changes)
style-d4e5f6.css  # Hash: d4e5f6
You can set far-future cache headers (1 year) because hashes change when content changes.

Configuration

Custom Build Config

Customize the build in vite.config.ts:
import { defineConfig } from 'vite'
import vinext from 'vinext'

export default defineConfig({
  plugins: [vinext()],
  build: {
    // Custom output directory
    outDir: 'build',
    
    // Source maps
    sourcemap: true,
    
    // Minification
    minify: 'esbuild', // or 'terser'
    
    // Target browsers
    target: 'es2020',
    
    // Chunk size warnings
    chunkSizeWarningLimit: 1000,
  },
})

Environment Variables

Build-time environment variables:
# .env.production
NEXT_PUBLIC_API_URL=https://api.production.com
NEXT_PUBLIC_GA_ID=G-XXXXXXXXXX
These are embedded into the client bundle at build time.

Examples

Basic Build

Build your app:
vinext build
Output:
vinext build  (Vite 6.0.0)

Building for production...
✓ Built RSC environment in 3.2s
✓ Built SSR environment in 2.1s  
✓ Built client environment in 4.5s

Build complete. Run `vinext start` to start the production server.

Build and Start

Build and immediately start the production server:
vinext build && vinext start

Build for Cloudflare Workers

Build with Cloudflare-specific config:
// vite.config.ts
import { defineConfig } from 'vite'
import vinext from 'vinext'
import { cloudflare } from '@cloudflare/vite-plugin'

export default defineConfig({
  plugins: [
    vinext(),
    cloudflare(),
  ],
})
Then build:
vinext build
Or use the one-command deploy:
vinext deploy  # Builds automatically

CI/CD Build

Typical CI build script:
{
  "scripts": {
    "build": "vinext build",
    "build:ci": "vinext build && npm run test:e2e"
  }
}

Build Performance

vinext builds are faster than Next.js:
Project SizeNext.jsvinextImprovement
Small (less than 20 pages)~15s~8s1.9x faster
Medium (20-100 pages)~45s~18s2.5x faster
Large (100+ pages)~120s~35s3.4x faster
Benchmarks from real-world projects. Your results may vary based on complexity and dependencies.

Troubleshooting

Build Fails with “Module not found”

Ensure all dependencies are installed:
npm install
For App Router, ensure @vitejs/plugin-rsc is installed:
npm install -D @vitejs/plugin-rsc

Out of Memory Error

Increase Node.js memory limit:
NODE_OPTIONS="--max-old-space-size=4096" vinext build
Or add to package.json:
{
  "scripts": {
    "build": "NODE_OPTIONS='--max-old-space-size=4096' vinext build"
  }
}

Large Bundle Size

Analyze your bundle:
npm install -D rollup-plugin-visualizer
// vite.config.ts
import { visualizer } from 'rollup-plugin-visualizer'

export default defineConfig({
  plugins: [
    vinext(),
    visualizer(),
  ],
})
After build, open stats.html to see what’s in your bundle.

Next Steps

start Command

Start the production server

deploy Command

Deploy to Cloudflare Workers

Build docs developers (and LLMs) love