sandbox_build
Runs an install or compile step and keeps its output, so a box with the same inputs restores it in seconds instead of building again.
| Input | Output |
|---|---|
id, dir, cmd, out, note, env, exclude, timeoutSec, noCache |
reused, cached, bytes, fingerprint, exitCode, stdout, stderr, ms |
Runs an install or compile step in dir and keeps its output. dir is relative to /work (app; /work/app works too), and out and exclude are relative to dir: { "dir": "app", "cmd": "npm ci", "out": ["node_modules"] } (an absolute path inside dir, such as /work/app/dist, works too). The fingerprint covers the contents of dir (minus derived folders such as node_modules and anything in exclude), cmd, env and the toolchain versions; when a box of yours has built the same fingerprint before, the paths in out are restored instead (reused: true, seconds instead of minutes). For an install step alone (npm ci, pnpm install, yarn, bun install, with flags, joined by && if you like) whose out is only node_modules folders, the version field of the package.json and package-lock.json at the top of dir is left out of the fingerprint, so bumping the version still reuses the install; dependency changes, and workspace packages' versions, still count. An install step does not read your sources, so exclude them (["src"]) and editing them no longer forces a reinstall. noCache: true builds anyway and replaces the stored output. cached: true means this run's output was saved so later boxes can reuse it; bytes is the size of what was saved. note works as in sandbox_exec.
Front ends that build in a box:
- Next.js with Turbopack refuses a
node_modulesthat is a symlink pointing outside the project (Symlink node_modules is invalid, it points out of the filesystem root). Letsandbox_buildrestorenode_modulesinto the project (out: ["node_modules"]), or copy it withcp -ainstead of linking it. - A large Vite or webpack build that dies with
JavaScript heap out of memoryhit Node's heap limit, not the box's memory (a size-1 box has 8 GB): raise it withNODE_OPTIONS=--max-old-space-size=6144, and when the build runs in a container, check itsdocker run --memory. - A big front end loads slowly on a phone or over a slow link from a dev server, because the browser fetches its module graph one file at a time (minutes on an iPhone for a large app). Build it once and serve the output instead:
vite build, thenvite preview(or any static server) with the same/apiproxy the dev server has, on the port you declared. Build-time variables come from the environment's.sh(. /work/.sbx/env/<service>.sh) or from secrets (Secrets); arequired-build-envcheck that stops the build is satisfied the same way, never with a key file left in/work.
Every tool and topic is listed in the tool reference.