Orbit
Configuring Your Build Command and Output Directory
Getting Orbit to build your project correctly comes down to a handful of fields in Settings: install command, build command, output directory, root directory and Node.js version. Left blank they are auto-detected, and most first-deploy problems come from an auto-detected value that does not match what your framework actually writes.
Where To Find the Settings
Open your project in Orbit, go to the Settings tab, and find the Build settings card.
| Field | What it does | Placeholder when blank |
|---|---|---|
| Install command | How dependencies are installed before the build | npm ci (auto-detected) |
| Build command | The command that produces your output | npm run build (auto-detected) |
| Output directory | The folder Orbit publishes after the build | dist (auto-detected) |
| Root directory | For monorepos, the subdirectory containing your app | / (monorepo subdirectory) |
| Node.js version | The major Node version to build and run with | Platform default |
Leave any field blank to let Orbit auto-detect. Click Save on the Build settings card to apply.

Changing a build setting does not change the deployment that is currently live. The new setting applies from the next deployment. Redeploy after saving, or nothing will appear to have happened.
Framework Defaults
Next.js
Next.js has two modes in Orbit, and picking the wrong one is the most common first-deploy mistake.
Static export (output: 'export' in next.config.js):
- Build command:
npm run build - Output directory:
out - Server mode: off
Server mode (SSR or ISR), which is most Next.js apps:
- Turn on Server mode in Settings, under Runtime
- Build command:
npm run build - Output directory:
.next
Without server mode enabled, a server-rendered Next.js app is published as static files. The home page will usually load and every dynamic route will 404. If that is your symptom, this is your cause: turn on server mode and redeploy before changing anything else.
Astro
Astro's output folder is dist in every mode. What changes is whether you need server mode.
output: 'static', the default: output directorydist, server mode offoutput: 'server'oroutput: 'hybrid': output directorydist, server mode on- Build command:
npm run build, orastro build
Vite (React, Vue, Svelte)
- Build command:
npm run build, orvite build - Output directory:
dist
Vite always writes to dist unless you have overridden build.outDir in vite.config.ts. If you have, set the output directory to match.
SvelteKit
- Build command:
npm run build - Output directory:
build
Whether you need server mode depends on your adapter: a static adapter does not, a Node adapter does.
Nuxt 3
- Build command:
npm run build - Output directory:
.output - Server mode: on
Remix
- Build command:
npm run build - Output directory:
build - Server mode: on
Express or a Plain Node API
- Build command:
npm run build - Output directory:
dist - Server mode: on
Server mode runs npm start after the build, so make sure your start script exists and starts the server.
Create React App
Create React App is deprecated upstream and is not a good choice for a new project, but existing ones build fine.
- Build command:
npm run build - Output directory:
build
Plain HTML or a Static Site Generator
- Leave the install command blank if there is no
package.json - Leave the build command blank to publish the repository as-is, or set your generator's command
- Output directory:
.for the repository root, or whatever folder the generator writes
Node.js Version
Enter the major version number only: 18, 20 or 22. The field hint says so explicitly. Anything else, such as 20.11.0 or v20, is not what this field expects.
The version applies to the build and, when server mode is on, to the runtime as well.
Pin the version rather than relying on the default. A dependency that needs a newer Node fails during install with an error that rarely says "wrong Node version" in so many words, and pinning removes that class of failure entirely.
Monorepos
Set Root directory to the path of your app, for example apps/web. Orbit changes into that directory before running your install and build commands, and the output directory is then relative to it.
The field hint spells out the second, more useful behaviour: pushes that change only files outside that path are skipped automatically. A monorepo with four Orbit projects rebuilds only the apps a commit actually touched, which saves both time and build minutes.
Each environment can override the root directory independently, under Staging: build overrides in Settings, which is useful when staging builds a different workspace.
Staging Overrides
If your project has a staging environment, Settings shows a Staging: build overrides section with the same fields. Any field left blank there inherits the project-level value, so you can change only the build command for staging, for example to npm run build:staging, and leave everything else alone.
Staging has its own related settings nearby: a branch, an access password, an IP allowlist, auto-rollback on failure, and an Inherit production env vars toggle.
Build Cache
Orbit caches node_modules between builds on the Liftoff and Apex plans. The deployment detail page shows Cache hit or Cold build, along with the install phase duration, so you can see what the cache is worth on your project.
To force a full reinstall, open Settings, click Clear build cache, and confirm.
Clearing the build cache cannot be undone, and the next deployment for every environment runs a full install from scratch. On a large monorepo that is a slow build, so do it deliberately rather than as a reflex.
Common Gotchas
"Build succeeded but the site shows a 404." The output directory is wrong: Orbit published a folder that is not your build output. Check what folder your build actually creates. Vite writes dist, Next.js static export writes out, Next.js server mode uses .next, Create React App and Remix write build, Nuxt writes .output.
"404 only on dynamic routes, the home page is fine." Server mode is off on an app that needs it. See the Next.js section above.
"Module not found" on the first deploy. Either the install step did not run, or it ran with a different package manager from the one you use locally. Set the install command explicitly: npm ci, yarn install --frozen-lockfile, or pnpm install --frozen-lockfile. Also check you have committed exactly one lockfile: if both package-lock.json and yarn.lock are in the repository, the detected package manager may not be the one you expect.
"Lockfile out of date." npm ci and the frozen-lockfile equivalents refuse to run when the lockfile disagrees with package.json. Run your package manager's install locally and commit the regenerated lockfile. This is the most common first-deploy failure and it never reproduces locally, which is exactly why it is confusing.
"Only one app in my monorepo is deploying." That is the root directory doing its job. Each app needs its own Orbit project with its own root directory.
"Wrong Node.js version." Set the Node.js version field to the major version number only.
The build runs out of memory or fills the disk. Both are plan limits on the build machine: Launch gets 1 vCPU, 1 GB RAM and 4 GB disk; Liftoff gets 2, 2 GB and 8 GB; Apex gets 4, 4 GB and 16 GB. Adding NODE_OPTIONS=--max-old-space-size=2048 as an environment variable helps only up to the machine's actual RAM. See Orbit Plan Limits.
Related Reading
- Supported Frameworks and Runtimes in Orbit
- Troubleshooting Failed Builds
- Environment Variables for build-time configuration