# Bun

> A Node.js project run by Bun rather than Node — the same application, chosen when it is ordered or with one line in vallic.yaml

Bun runs a Node.js project in Node's place: the same project type, the same port, the same `node_modules` in the release, with Bun as the runtime and the package manager. It serves its own HTTP — `Bun.serve`, Hono, Elysia, Next.js or anything else that listens on a port — and replaces PHP-FPM and nginx rather than joining them, as Node does.

It is chosen in `vallic.yaml`, where the version is written: `bun:` under `runtime`, in place of `node:`. The project stays a Node.js project, `type: nodejs`, and going back to Node is the same line the other way round. The deploy that changes it builds the release in the new image and replaces the container.

It can be chosen when the project is ordered too, as what a Node.js application runs on, and the project then starts on Bun: its suggested `vallic.yaml` names `bun:`, and a repository that names neither runs on Bun. What the repository says comes first — `node:` under `runtime` is Node.js, whatever was chosen then.

The container runs as `vallic` with the release at `/var/www/html/current` (`WEB_ROOT`), read-only, the release's own `node_modules/.bin` on `PATH`, and `node` answering as Bun for the scripts whose first line asks for node. `Bun.sql` connects to `DATABASE_URL` when it is given no other address, and the platform sets that for the environment's database.

## A Bun project

`vallic.yaml` at the root of the repository:

```yaml
version: 1
type: nodejs

runtime:
  bun: '1.4'

build:
  steps:
    - name: Dependencies
      run: bun install --frozen-lockfile
    - name: Production dependencies only
      run: rm -rf node_modules && bun install --frozen-lockfile --production
  cache:
    - node_modules

start: bun index.ts
port: 3000

health:
  path: /
  timeout: 30
```

`Bun.serve` listens on `PORT` when it is given no port, and on every address, so a server written without either needs no `port` here. Left out, `start` is `bun run start`: the `start` script in your `package.json`.

Bun's download cache is kept between builds, as npm's is. Bun has no `prune`, so the last step installs again with `--production`, into an empty `node_modules` and from that cache: the release keeps only what production needs. A project with no dependencies — Bun's own APIs and nothing else — has no lockfile and needs no build at all.

Uploads and anything else written at runtime go under `/mnt/files` (`VALLIC_PUBLIC_DIR`, `VALLIC_PRIVATE_DIR`), which outlive the release; the release itself is read-only. Environment variables are set on the environment in the console and reach the process as ordinary environment variables. Bun reads `.env` files from the release as well, but anything secret belongs in the console, not in the repository.

## Versions

| Version | Status |
| --- | --- |
| `1.4` | Supported, and the default |
| `1.3` | Supported |

Pin the version, not the build: name `1.4` and the platform matches it to the
current build, so a security rebuild reaches you without anybody editing a
repository.

## What you can change

In [`vallic.yaml`](configuration.md) — what each one does is on [Service settings](service-settings.md):

```yaml
services:
  - bun:
      version: '1.4'
      environment:
        BUN_OPTIONS: …
        BUN_CONFIG_MAX_HTTP_REQUESTS: …
```

Anything not on this list refuses the deploy, naming the variable — rather
than being accepted and quietly ignored.
