# Build settings

> The Node version, the package manager, the commands and the port of an app, how each is chosen from your repository, and the limits of a build.

The build settings say how your code becomes a running app. Most are filled in from your repository when you create the app. You find them later under **Settings**, **Build and start**.

A change takes effect with the next deployment. Saving does not deploy.

## The settings

| Setting | If you set nothing | What it is |
| --- | --- | --- |
| Branch | Chosen when you create the app | The branch that is deployed |
| Root directory | The top of the repository | The folder with your `package.json` |
| Node version | 22 | 18, 20 or 22 |
| Port | 3000 | The port your server listens on. Also set as the `PORT` variable |
| Install command | Automatic, from your lockfile | How packages are installed |
| Build commands | From your `package.json` | What runs after the install |
| Start command | `npm run start` | What starts your server |

## Detect from repository

**Detect from repository** reads your code again and suggests values. Nothing is saved until you save.

Use it after you changed `.nvmrc`, `engines.node` or the scripts in `package.json`. The settings do not follow the repository by themselves: the saved value is what a build uses.

## Node version

Node.js 18, 20 and 22 are available. 22 is used when nothing says otherwise.

The suggestion comes from `.nvmrc` first, then from `engines.node` in `package.json`. A `.node-version` file is not read.

If your code asks for a version that is not available, the closest one is suggested: 16 becomes 18, 24 becomes 22.

## Package manager

There is nothing to choose. The lockfile in the root directory decides:

| Lockfile | Package manager | Install command |
| --- | --- | --- |
| `pnpm-lock.yaml` | pnpm | `pnpm install --frozen-lockfile` |
| `yarn.lock` and `.yarnrc.yml` | Yarn 2 or newer | `yarn install --immutable` |
| `yarn.lock` | Yarn 1 | `yarn install --frozen-lockfile` |
| `package-lock.json` | npm | `npm ci` |
| None | npm | `npm install` |

Commit your lockfile and keep it in step with `package.json`. With pnpm and Yarn, a lockfile that does not match fails the build.

pnpm and Yarn are started through Corepack, so the version in the `packageManager` field of your `package.json` is the one that runs.

## Install command

Leave it empty and packages are installed as in the table above. Set a command only to install your own way. It is one line.

## Packages your build needs

When your app has a build command, the install brings in everything in `package.json`, also the packages in `devDependencies` (TypeScript, a bundler). This is so with every package manager, and with an install command of your own.

`NODE_ENV` becomes `production` after the install. Your build and your running app both see it.

After the build, the packages from `devDependencies` are removed again. The running app does not have them, so the start command must not need one.

Without a build command, the packages in `devDependencies` are not installed at all.

> **Scripts that run on install**
>
> A `prepare` or `postinstall` script runs during the install. Without a build command, a tool from `devDependencies` is not there (husky is the usual one), and the install fails when the script calls it. Make the script skip the tool when it is missing.

## Build commands

One command per line. They run in order after the install, and the build stops at the first one that fails.

When you create the app, the build command is filled in like this:

| Your repository has | Build command |
| --- | --- |
| A `build` script in `package.json` | `npm run build` |
| A `tsconfig.json` and no `build` script | `npx tsc` |
| Neither | No build step |

## Start command

`npm run start` unless you change it. If your `package.json` has no `start` script but a `main` file, `node` with that file is suggested.

A TypeScript app starts its built file, `node dist/server.js` for example.

## Port

Your server has to listen on this port. The platform sets it as the `PORT` variable, so `process.env.PORT` always has the right value. See [Express](https://arrangic.com/docs/frameworks/express.md#port-and-address).

## Root directory

Leave it empty when `package.json` is at the top of the repository. Set it to a folder, `apps/api` for example, when the app lives in one.

Only that folder becomes the app. Files outside it are not there, and the lockfile has to be inside it. A workspace whose packages depend on each other across folders does not work yet.

## What is not used

- **Variables during install and build.** The [environment variables](https://arrangic.com/docs/environment-variables.md) you set are there for deploy commands and for the running app. The install and the build get only the ones with **Build** turned on. See [During the build](https://arrangic.com/docs/environment-variables.md#during-the-build).
- **Your Dockerfile.** A `Dockerfile`, `.dockerignore` or `docker-compose.yml` in the repository is ignored. The app is built from `package.json`.
- **System packages.** Only your npm packages are installed. A package that has to compile native code during the install can fail, because there is no compiler.

## Limits

| | Limit |
| --- | --- |
| Build time | 30 minutes |
| Repository size | 1 GB |
| Build log | The first 1 MB of output is kept. The build goes on after that |

A command line cannot start with a dash or end with a backslash.

---

This page on the site: https://arrangic.com/docs/build-settings  
All pages of the documentation: https://arrangic.com/llms.txt
