Skip to content

Node.js & Express ​

This works for Express, Fastify, Koa, Hono, NestJS and any other Node.js server.

A minimal app ​

js
// server.js
const express = require('express')

const app = express()
const port = process.env.PORT || 8080

app.get('/', (req, res) => res.send('Hello from Express'))

app.listen(port, '0.0.0.0', () => console.log(`listening on ${port}`))
json
{
  "scripts": { "start": "node server.js" },
  "dependencies": { "express": "^5.1.0" }
}

What Zenavo detects ​

zbpack builds it as Node.js:

StepCommand
Installnpm install, pnpm install, yarn install or bun install, after the lockfile in the repository (yarn without one)
Buildthe build script, when there is one (TypeScript, bundlers)
Startthe start script; without one, node index.js

The Node.js version comes from engines.node in package.json (22 when it is not set):

json
"engines": { "node": "22" }

To use other commands, set ZBPACK_BUILD_COMMAND or ZBPACK_START_COMMAND under Settings → Build → zbpack options (Build Plan).

Deploy ​

  1. Add Service → GitHub, pick the repository and branch.
  2. Add variables, click Next, check the preview shows nodejs, and click Deploy.
  3. Generate a domain on the Networking tab.

Connect a database ​

Add a database to the project and reference its variables from the app's service:

sh
DATABASE_URL=${POSTGRESQL_CONNECTION_STRING}
REDIS_URL=${REDIS_CONNECTION_STRING}

Run migrations when the app starts, not in the build: builds cannot reach the project's databases. A predeploy script in package.json runs before start every time the service starts:

json
"scripts": {
  "predeploy": "node migrate.js",
  "start": "node server.js"
}

TypeScript ​

Compile in the build script and start the output:

json
"scripts": {
  "build": "tsc",
  "start": "node dist/server.js"
}

Keep typescript in dependencies or devDependencies; both are installed for the build.

Common problems ​

SymptomCause
Deploy never becomes healthyThe server listens on localhost or a fixed port. Listen on 0.0.0.0 and process.env.PORT.
Cannot find module at startThe start script points at a file the build did not produce, or a dependency is missing from package.json.
The wrong package manager is usedThe lockfile is missing or there are two of them. Keep exactly one.
Uploaded files disappear after a deployThe container's disk is replaced on every deploy. Use a volume or object storage.

Not affiliated with Zeabur.