vinext
Documentation menu

Documentation

Deploy to other platforms

Build a standalone Node server or use Nitro's Vite plugin for more deployment targets.

Standalone Node.js

Set output: "standalone" in next.config. A production build then emits a self-contained server under dist/standalone.

pnpm exec vite build
node dist/standalone/server.js

Set PORT and HOST to change the default bind address. Unlike Next.js standalone output, vinext uses HOST, not HOSTNAME.

Custom standalone entries

The generated server.js is a small wrapper around startProdServer from vinext/server/prod-server. To control where the server loads the build output from, write your own entry and call startProdServer directly. All options are optional:

OptionDefaultDescription
portPORT env var, otherwise 3000Port to listen on.
host"0.0.0.0"

Address to bind to. Unlike the generated server.js, startProdServer doesn't read HOST, so pass process.env.HOST yourself if you need it.

outDirdist, resolved against the current directory

Build output directory containing client/ and server/. Relative paths resolve against the current directory. In standalone output, this is dist/standalone/dist.

serverDir<outDir>/serverDirectory containing the server bundles, manifests, and prerendered output.
rscEntryPath<serverDir>/index.jsApp Router server entry. If this file exists, the server runs in App Router mode.
serverEntryPath<serverDir>/entry.jsPages Router server entry. Used when there's no App Router entry.
noCompressionfalseDisable response compression.

ProdServerOptions also has purpose and silent, which vinext uses for its own build-time servers. Leave them unset. The returned promise resolves to { server, port } once the server is listening.

Compiled single-file binaries

A bun build --compile binary can't use the generated server.js. Bun fixes import.meta.dirname when it compiles the binary, so join(import.meta.dirname, "dist") doesn't point at the directory the binary runs from. Depending on the Bun version, it points at the build machine's path or at Bun's embedded /$bunfs/root. Resolve outDir from the executable's location instead:

// server-bin.mjs, in your project root
import path from "node:path";
import { startProdServer } from "vinext/server/prod-server";

await startProdServer({
  port: Number.parseInt(process.env.PORT ?? "3000", 10),
  host: process.env.HOST ?? "0.0.0.0",
  outDir: path.join(path.dirname(process.execPath), "dist"),
});
bun build --compile --compile-autoload-package-json server-bin.mjs --outfile dist/standalone/server

Keep the entry outside dist/standalone: each build deletes and recreates that directory. Compile after vite build, then ship the whole dist/standalone directory, because the server binary needs the dist/ and node_modules/ directories next to it. The server bundles in dist/server still import their dependencies from node_modules at runtime. --compile-autoload-package-json lets the binary read package exports and main fields when it resolves them. Under plain Node, process.execPath is the Node binary, so use this entry only for compiled builds.

Nitro adapters

Add Nitro when you need a deployment preset for Vercel, Netlify, AWS, Deno Deploy, Azure, or another supported host.

import { nitro } from "nitro/vite";
import { defineConfig } from "vite";
import vinext from "vinext";

export default defineConfig({
  plugins: [vinext(), nitro()],
});

Follow the Nitro deployment guide for host-specific presets and output. On Cloudflare, prefer vinext's native integration for direct bindings, caching, image optimization, and the one-command deployment workflow.