> ## 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.

# vinext build

> Build your Next.js app for production with Vite

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

```bash theme={null}
vinext build [options]
```

## Options

<ParamField path="--help" type="flag">
  Show help for this command. Can also use `-h`.

  ```bash theme={null}
  vinext build --help
  ```
</ParamField>

## Behavior

### Router Detection

vinext automatically detects your router type and runs the appropriate build:

<CodeGroup>
  ```bash App Router Build theme={null}
  # 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.
  ```

  ```bash Pages Router Build theme={null}
  # Detects pages/ or src/pages/ (no app/ directory)
  vinext build

  # Output:
  #   vinext build  (Vite 6.0.0)
  #
  #   Building client...
  #   ✓ Built in 2.5s
  #   Building server...
  #   ✓ Built in 1.8s
  #
  #   Build complete. Run `vinext start` to start the production server.
  ```
</CodeGroup>

### App Router Build Process

For App Router projects, vinext uses `createBuilder()` to run a multi-environment build:

```typescript theme={null}
// 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:

```typescript theme={null}
// 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

<CodeGroup>
  ```bash App Router Output theme={null}
  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
  ```

  ```bash Pages Router Output theme={null}
  dist/
  ├── client/
  │   ├── assets/          # JS/CSS bundles
  │   │   ├── index-a1b2c3.js
  │   │   ├── about-b2c3d4.js
  │   │   └── style-c3d4e5.css
  │   └── .vite/
  │       ├── manifest.json       # Asset manifest
  │       └── ssr-manifest.json   # SSR manifest
  └── server/
      └── entry.js         # SSR entry point
  ```
</CodeGroup>

### Build Artifacts

<AccordionGroup>
  <Accordion title="Client Assets">
    * **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
  </Accordion>

  <Accordion title="Server Entry">
    * **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
  </Accordion>

  <Accordion title="Manifests">
    * **manifest.json**: Maps module IDs to built asset paths
    * **ssr-manifest.json**: Maps Client Component imports to asset URLs for preloading
  </Accordion>
</AccordionGroup>

## Build Optimizations

vinext applies these optimizations automatically:

### Code Splitting

Each page/route gets its own bundle:

```bash theme={null}
# 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:

```bash theme={null}
  vendor-d4e5f6.js     # node_modules code
  shared-e5f6a7.js     # Shared page code
```

### Tree Shaking

Unused code is eliminated at build time:

```typescript theme={null}
// 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:

```bash theme={null}
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`:

```typescript theme={null}
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:

```bash theme={null}
# .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:

```bash theme={null}
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:

```bash theme={null}
vinext build && vinext start
```

### Build for Cloudflare Workers

Build with Cloudflare-specific config:

```typescript theme={null}
// 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:

```bash theme={null}
vinext build
```

Or use the one-command deploy:

```bash theme={null}
vinext deploy  # Builds automatically
```

### CI/CD Build

Typical CI build script:

```json theme={null}
{
  "scripts": {
    "build": "vinext build",
    "build:ci": "vinext build && npm run test:e2e"
  }
}
```

## Build Performance

vinext builds are faster than Next.js:

| Project Size               | Next.js | vinext | Improvement |
| -------------------------- | ------- | ------ | ----------- |
| Small (less than 20 pages) | \~15s   | \~8s   | 1.9x faster |
| Medium (20-100 pages)      | \~45s   | \~18s  | 2.5x faster |
| Large (100+ pages)         | \~120s  | \~35s  | 3.4x faster |

<Note>
  Benchmarks from real-world projects. Your results may vary based on complexity and dependencies.
</Note>

## Troubleshooting

### Build Fails with "Module not found"

Ensure all dependencies are installed:

```bash theme={null}
npm install
```

For App Router, ensure `@vitejs/plugin-rsc` is installed:

```bash theme={null}
npm install -D @vitejs/plugin-rsc
```

### Out of Memory Error

Increase Node.js memory limit:

```bash theme={null}
NODE_OPTIONS="--max-old-space-size=4096" vinext build
```

Or add to package.json:

```json theme={null}
{
  "scripts": {
    "build": "NODE_OPTIONS='--max-old-space-size=4096' vinext build"
  }
}
```

### Large Bundle Size

Analyze your bundle:

```bash theme={null}
npm install -D rollup-plugin-visualizer
```

```typescript theme={null}
// 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

<CardGroup cols={2}>
  <Card title="start Command" icon="play" href="/api/cli/start">
    Start the production server
  </Card>

  <Card title="deploy Command" icon="rocket" href="/api/cli/deploy">
    Deploy to Cloudflare Workers
  </Card>
</CardGroup>
