# Node.js app recipe

URL: https://briq.cloud/cookbook/node

> Your Node.js code running as a service, from files or a GitHub repo: it installs package.json and starts it. No image to build.

Tags: app, language

Guides:

- [Run your own app](https://briq.cloud/docs/guides/run-your-own-app.md): Your code as a running service, with a URL, in one call and no image to build.
- [Run a GitHub repo](https://briq.cloud/docs/guides/run-a-github-repo.md): An app from a repo, running with a URL. The briq downloads the code itself, and nothing is built on your side.

## Run it

MCP:

```ts
briq_run({
  recipe: "node",
  params: {
    "version": "22",
    "packages": [],
    "port": 8080,
    "env": {},
    "size": "small"
  },
  wait: true
})
```

REST:

```bash
curl -X POST https://api.briq.cloud/v1/briqs \
  -H "Authorization: Bearer $BRIQ_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "recipe": "node",
    "params": {
      "version": "22",
      "packages": [],
      "port": 8080,
      "env": {},
      "size": "small"
    },
    "wait": true
  }'
# → { "briqs": [{ "id": "bq_…", … }], "outputs": { "APP_URL": "…" }, … }

# ... when done, for each briq id
curl -X DELETE https://api.briq.cloud/v1/briqs/<id> \
  -H "Authorization: Bearer $BRIQ_API_KEY"
```

## Parameters

| Name | Type | Options | Default | What it does |
| --- | --- | --- | --- | --- |
| `version` | enum | 22, 24 | "22" | — |
| `files` | record | { "path": "content" \| { base64 } } | — | Your app's files, path → content (text, or { base64 }). Relative paths go under /app. For a bigger app, or one already on GitHub, pass `repo` instead. Without either, a hello-world app. |
| `repo` | object | { url, ref?, dir?, token? } | — | Your code from a repo instead of `files`. url: "github.com/owner/app", or on another host (GitLab, Bitbucket, Codeberg) the https URL of a .tar.gz archive, without ref. ref: a branch, tag or commit sha; default branch; a full sha pins the code. dir: the app's folder, e.g. "backend". token, private repos only: { secret: "GITHUB_TOKEN", value }, a fine-grained token with Contents: read on this repo; never the person's own token. The briq downloads the code itself, installs when a lockfile changed, runs `build` when the commit changed, then `start` |
| `packages` | string[] | — | [] | Extra packages to install at each start, besides your manifest |
| `install` | string | — | — | Shell command replacing the default install step: run before each start; with `repo`, only when a lockfile changed (go and rust build here, at each start) |
| `build` | string | — | — | Shell command run after the install, e.g. "npm run build": with `repo`, only when the commit or the install changed; with files, at each start |
| `start` | string | — | — | Shell command that starts the app (it must not exit). With `repo`, pass it: the default (python app.py, ruby app.rb…) rarely matches a repo; node runs npm start, bun bun run start |
| `port` | number | — | 8080 | — |
| `env` | record | { NAME: "value" \| { secret, value? } } | {} | Env vars. A credential goes as { secret: "NAME", value: "…" }: stored encrypted and never shown again |
| `size` | enum | nano, small, medium, large | "small" | A build (Next.js, Nuxt, a Rust release, a Go toolchain) is many times faster on medium or large: small has one shared CPU, slowed down once a long build used its burst. Up to small, a sleeping briq wakes from a memory snapshot in seconds; medium and large start from scratch on a wake (with `repo`: the branch is looked up again, and a new commit is installed and built before the app answers) |
| `diskGb` | number | — | — | With `repo` only: the size in GB of the volume (/work) that holds the code, its dependencies and build caches |

## Outputs

Returned by `briq_run` once the stack is healthy. Hosts resolve inside your team network; secrets are generated per run.

| Output | Value |
| --- | --- |
| `APP_URL` | `http://app.<stack>.internal:8080` |

## What it runs

| Briq | Image | Ports | Size | Volume |
| --- | --- | --- | --- | --- |
| app | `node:22-slim` | 8080 | small | — |

## When to use it

* You wrote an Express, Fastify or plain `node:http` server and want it running next to its
  database, with a URL, without building an image.
* A webhook receiver, an API mock or a small bot should run as a service.

## Tips

* **Code in a repo**: pass `repo: { url: "github.com/owner/app" }` instead of `files`. See
  [Run a GitHub repo](https://briq.cloud/docs/guides/run-a-github-repo).
* **A bot or a scheduler** that only makes outgoing calls is not seen as use, so it sleeps after
  its `sleep` window. Give it `sleep: "never"` (always on, Pro plan and above), or a window longer
  than the gap between its runs.
* **Pass the code as `files`**: `{ "server.js": "…", "package.json": "…" }`. Relative paths go
  under `/app`, the working directory, written before the app starts and again whenever it starts over.
* **`package.json` is installed at each start** (`npm ci` when there is a lockfile);
  `packages: ["express"]` adds more without one. They stay on the disk, so restarts are quick.
* **`start`** is the command when it is not `node server.js`, e.g. `"npm start"`.
* **Yarn 2 and later** need the `packageManager` field in `package.json` (`yarn set version`
  writes it): without it, corepack runs Yarn 1 instead of the version the repo was made with.
* **Listen on `::` and on `process.env.PORT`** (8080 by default).
* **No build step**: ship JavaScript, or use the [bun](https://briq.cloud/cookbook/bun) recipe to run TypeScript
  as it is.
* **Publish it as you run it** with `expose: "private"` (or `"public"` for anyone): it returns `URL`.
* **Step by step**: [Run your own app](https://briq.cloud/docs/guides/run-your-own-app), with a database and a URL.
