Appearance
Node.js and package managers
Node.js version
The builder uses the first version it finds, in this order (in the app folder, then the repository root):
engines.nodeinpackage.json.nvmrc.node-version.tool-versions(nodejsornodeline)volta.nodeinpackage.json
Without any of these, it uses Node.js 22.
Ranges resolve to the newest LTS release they allow, from 24, 22, 20 and 18. For example >=18 gives 24, ^20 gives 20, lts/iron gives 20 and lts/* gives 24. A non-LTS major that a project pins exactly (for example 23) is used as is, with a note in the build log. The image is node:<major>-bookworm-slim.
TIP
Pin the major you develop with, for example "engines": { "node": "22.x" } or an .nvmrc with 22. Current versions of Vite, Nuxt and Astro need Node.js 20 or newer; see Troubleshooting.
Package manager
Chosen from the lockfile:
| Lockfile | Package manager | Install command |
|---|---|---|
pnpm-lock.yaml | pnpm | pnpm install --frozen-lockfile |
yarn.lock | Yarn 1 or Yarn Berry (2+) | yarn install --frozen-lockfile / yarn install --immutable |
bun.lock, bun.lockb | Bun | bun install --frozen-lockfile |
package-lock.json, npm-shrinkwrap.json | npm | npm ci |
| none | from packageManager in package.json, else npm | npm install |
The packageManager field (for example pnpm@9.15.0) also sets the version. Otherwise the pnpm version is inferred from the lockfile format and Yarn Berry is detected from .yarnrc.yml or the lockfile. Bun projects run on the oven/bun image.
Because installs use the lockfile strictly, a lockfile that is out of date with package.json fails the build. Commit the lockfile after changing dependencies.
Native modules and git dependencies
If your dependencies include native modules such as bcrypt, better-sqlite3, sqlite3, canvas, argon2 or node-sass, the build image gets python3, make and g++. Dependencies installed from git get git.
Workspaces
npm, pnpm and Yarn workspaces are installed once at the workspace root. The builder then builds the app that the root build script points at, or the only framework app in the workspace. With several apps, set the root directory of each service to its app's folder.
Limits: Yarn Plug'n'Play and Bun projects keep the whole build output in the image (no pruning).
Environment during the build
Builds run with NODE_ENV=production and NODE_OPTIONS=--max-old-space-size=1536 (so V8 may use swap beyond the build's memory limit), with telemetry of Next.js, Nuxt, Astro and Gatsby turned off. The running app gets NODE_ENV=production, HOST=0.0.0.0 and PORT.