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.

Starts a production HTTP server to serve the output from vinext build. Supports SSR, static file serving, compression, and middleware.

Usage

vinext start [options]
You must run vinext build before vinext start. The start command serves the built output from the dist/ directory.

Options

--port
number
default:"3000"
Port to listen on. Can also use the short form -p. Defaults to the PORT environment variable if set.
vinext start --port 8080
vinext start -p 8080

# Or using environment variable
PORT=8080 vinext start
--hostname
string
default:"0.0.0.0"
Hostname to bind to. Can also use the short form -H.
vinext start --hostname localhost
vinext start -H 127.0.0.1
Default is 0.0.0.0 (all interfaces) in production, unlike dev mode which defaults to localhost.
--help
flag
Show help for this command. Can also use -h.
vinext start --help

Behavior

Server Implementation

The production server is implemented in server/prod-server.ts and provides:
// From cli.ts:273-281
const { startProdServer } = await import(
  "./server/prod-server.js"
);

await startProdServer({
  port,
  host,
  outDir: path.resolve(process.cwd(), "dist"),
});
Features:
  • Static asset serving: Serves files from dist/client/
  • SSR rendering: Server-side renders pages on request
  • API route handling: Routes /api/* requests to server handlers
  • Compression: Gzip and Brotli compression for text-based responses
  • Streaming SSR: Supports React 18 streaming for App Router

Request Handling

The production server handles requests in this order:
  1. Middleware/Proxy (if exists)
  2. Redirects (from next.config)
  3. Rewrites (from next.config)
  4. Static assets (dist/client/)
  5. API routes (/api/*)
  6. Page routes (SSR)
  7. 404 page (if no match)

Response Compression

The server automatically compresses responses:
// From prod-server.ts:54-69
const COMPRESSIBLE_TYPES = new Set([
  "text/html",
  "text/css",
  "text/javascript",
  "application/javascript",
  "application/json",
  "image/svg+xml",
  "application/manifest+json",
]);
Encoding preference: Brotli > Gzip > Deflate > Identity Minimum threshold: 1024 bytes (files smaller than 1KB are not compressed)

SSR Output

For Pages Router, the server loads the SSR entry:
// dist/server/entry.js exports:
export { renderPage, handleApiRoute }
For App Router, the server loads the RSC entry:
// dist/server/index.js exports:
export default {
  async fetch(request: Request): Promise<Response>
}

Examples

Basic Usage

Start production server on default port (3000):
vinext build
vinext start
Output:
vinext start  (port 3000)

  Production server running at:
  ➜  http://0.0.0.0:3000/

Custom Port

Start on port 8080:
vinext start --port 8080
Or:
vinext start -p 8080

Using Environment Variables

PORT=8080 vinext start
Or add to .env.production:
PORT=8080

Bind to Localhost Only

For security on shared hosts:
vinext start --hostname localhost

Production npm Script

Add to package.json:
{
  "scripts": {
    "build": "vinext build",
    "start": "vinext start",
    "prod": "vinext build && vinext start"
  }
}
Then:
npm run prod

Deployment

Node.js Deployment

For traditional Node.js hosting:
# Build on your CI server
vinext build

# Deploy dist/ directory and node_modules
# Start with:
vinext start --port 80 --hostname 0.0.0.0

Docker Deployment

# Dockerfile
FROM node:20-slim

WORKDIR /app

# Install dependencies
COPY package*.json ./
RUN npm ci --only=production

# Copy built files
COPY dist ./dist
COPY next.config.* ./
COPY vite.config.* ./

# Start production server
EXPOSE 3000
CMD ["npx", "vinext", "start"]
Build and run:
docker build -t my-app .
docker run -p 3000:3000 my-app

Cloudflare Workers

For Cloudflare Workers, use vinext deploy instead:
vinext deploy
This builds and deploys in one command. See the deploy command for details.

Process Management

Using PM2

For production deployments with auto-restart:
npm install -g pm2

# Start with PM2
pm2 start "vinext start" --name my-app

# View logs
pm2 logs my-app

# Restart
pm2 restart my-app

# Stop
pm2 stop my-app

Using systemd

Create /etc/systemd/system/my-app.service:
[Unit]
Description=My vinext App
After=network.target

[Service]
Type=simple
User=www-data
WorkingDirectory=/var/www/my-app
ExecStart=/usr/bin/npx vinext start
Restart=on-failure
Environment=NODE_ENV=production
Environment=PORT=3000

[Install]
WantedBy=multi-user.target
Enable and start:
sudo systemctl enable my-app
sudo systemctl start my-app
sudo systemctl status my-app

Performance

Response Times

Typical server response times:
Route TypeCold StartWarm
Static assetless than 1msless than 1ms
SSR page (cached)5-15ms2-5ms
SSR page (fresh)20-50ms10-20ms
API route5-20ms2-10ms
Benchmarks from a medium-complexity app on modern hardware. Actual times vary by complexity.

Compression Impact

Typical compression ratios:
Content TypeOriginalGzipBrotli
HTML100KB20KB (80%)18KB (82%)
JavaScript500KB150KB (70%)130KB (74%)
CSS50KB12KB (76%)10KB (80%)
JSON100KB10KB (90%)8KB (92%)

Caching Strategy

The server sets these cache headers:
// Static assets (hashed filenames)
Cache-Control: public, max-age=31536000, immutable

// HTML pages (SSR)
Cache-Control: public, max-age=0, must-revalidate

// API routes (no cache by default)
Cache-Control: no-store

Troubleshooting

”dist/ directory not found”

You forgot to build first:
vinext build
vinext start

Port Already in Use

Another process is using the port:
# Find what's using port 3000
lsof -ti:3000

# Kill the process
kill -9 $(lsof -ti:3000)

# Or use a different port
vinext start --port 3001

Pages Not Loading (404)

Check the build output:
ls dist/client
ls dist/server
Ensure both directories exist and contain files.

High Memory Usage

The server loads all pages into memory. For very large apps:
  1. Increase Node.js heap size:
    NODE_OPTIONS="--max-old-space-size=4096" vinext start
    
  2. Or deploy to Cloudflare Workers (no memory limits):
    vinext deploy
    

Monitoring

Health Check Endpoint

Add a health check page:
// pages/api/health.ts
export default function handler() {
  return Response.json({ status: 'ok' })
}
Then monitor:
curl http://localhost:3000/api/health
# {"status":"ok"}

Access Logs

The production server logs all requests to stdout:
GET /about 200 12ms
GET /api/users 200 45ms
POST /api/contact 201 67ms
Redirect logs to a file:
vinext start > access.log 2>&1

Next Steps

deploy Command

Deploy to Cloudflare Workers

Deployment Guide

Learn about deployment options

Build docs developers (and LLMs) love