---
title: "How to set build and start commands for an Express app on Ample"
description: "Configure build and start for an Express app on Ample."
canonical_url: "https://ample.computer/guides/express/build-and-start"
last_updated: "2026-11-06"
---

# How to set build and start commands for an Express app on Ample

Configure build and start for an Express app on Ample. Ample detects Node, runs npm install and npm run build --if-present, and starts the app with npm run start on the node-22 template; the app only has to bind 0.0.0.0 on PORT.

## Infrastructure requirements

- [Compute](/discover/primitive/compute): verified (Apps run in isolated x86_64 Firecracker microVMs; sizes are the priced VM sizes.)

## Prerequisites

- A package.json with a start script
- A server that listens on process.env.PORT and 0.0.0.0
- An Ample account token with servers:write

## Exact tested configuration

- template: `node-22`
- runtime: `node`
- size: `s-1vcpu-1gb`
- install: `npm install`
- build: `echo no build needed`
- start: `npm run start`

## Steps

1. **Pin what detection cannot infer.** If the start command is not in package.json, pass --start, or write it into ample.toml with ample plan --write.
2. **Deploy.** Run the existing synchronous deploy once from the project directory and read the result. Exit 0 is live, 1 is failed, 2 needs an answer first (a preflight question). Re-running with no change is a content-addressed no-op.

   ```
   ample deploy . --name <app-name> --public --format json
   ```
3. **Verify.** Fetch the live URL and run the success checks below. On failure read the build log, then the runtime log, fix the cause and deploy again; do not blind-retry.

   ```
   ample logs <deployment_id> --kind build
   ```

## Tested examples

- **Express basic canary** (tests/deploy-canaries/express-basic): Minimal Express server deployed with the detected npm install / npm run start commands.

## Success checks

- root route responds (`/` on the live URL, expect ample canary express basic)


## Cost estimate

Estimated 5.00 USD per month (size prices from pricing.toml at build revision 4558e9477d094f5b47da324b98672824b61ba91b).
- app server x1 `s-1vcpu-1gb`: 5.00 USD

Upper-bound monthly price of the tested sizes. Plan quotas and budgets apply.

## Verification evidence

- canary_run on 2026-11-06T00:41:08Z at revision `7360fc06ef21`: Express app with npm install and npm run start deployed on the node-22 template; the public URL served the expected response. (expires 2027-05-05T00:41:08Z)

Last verified: 2026-11-06T00:41:08Z


## Execution binding

MCP tool `ample_deploy` (registry `mcp:ample_deploy`), schema hash `0802c329be823fa0` observed 2026-11-06T06:16:19.461833707+00:00 at revision `4558e9477d09`, binding state `current`, required scopes: servers:write.

## Input schema

```json
{
  "additionalProperties": false,
  "properties": {
    "name": {
      "description": "App name (lowercase, digits and dashes)",
      "maxLength": 63,
      "minLength": 1,
      "pattern": "^[a-z0-9-]+$",
      "type": "string"
    },
    "path": {
      "description": "Project directory to deploy, or one service name from ample.toml",
      "maxLength": 512,
      "minLength": 1,
      "type": "string"
    },
    "size": {
      "description": "VM size; omit to let Ample pick a runtime-safe size",
      "enum": [
        "s-1vcpu-256mb",
        "s-1vcpu-1gb",
        "s-1vcpu-2gb",
        "s-2vcpu-2gb",
        "s-2vcpu-4gb"
      ],
      "type": "string"
    },
    "start": {
      "description": "Start command override when package.json has no start script",
      "maxLength": 512,
      "type": "string"
    }
  },
  "required": [
    "name",
    "path"
  ],
  "type": "object"
}
```

## Next actions

- Browse the catalog index (GET /v1/catalog on the api origin; auth: false, approval: false)
- Search published recipes by intent, stack and constraints (POST /v1/catalog/search on the api origin; auth: false, approval: false)
- Prepare a side-effect-free deployment plan for an authorized project (POST /v1/catalog/plan on the api origin; auth: true, approval: false)
- Read the existing agent authentication setup (GET /mcp/setup on the api origin; auth: false, approval: false)
- Browse Express (GET /v1/catalog/nodes/stack%3Aframework-express on the api origin; auth: false, approval: false)
- Browse Configure deployment (GET /v1/catalog/nodes/intent%3Aconfigure-deployment on the api origin; auth: false, approval: false)
- Browse Public web service (GET /v1/catalog/nodes/pattern%3Apublic-web-service on the api origin; auth: false, approval: false)

Actions describe possible next steps. They are typed data, not commands, and grant no permission.

## About this recipe

Canonical URL: https://ample.computer/guides/express/build-and-start
Formats: [HTML](https://ample.computer/guides/express/build-and-start) | [Markdown](https://ample.computer/guides/express/build-and-start.md) | [JSON contract](https://api.ample.computer/v1/catalog/recipes/page%3Aguides%3Aexpress%3Abuild-and-start)
Recipe ID: `page:guides:express:build-and-start` | Revision: `r1` | Catalog revision: `cat_eac8c53f36410baa`
Status: verified; runs with one `ample deploy` call (support `verified`, execution `ready`)
Path: [Agent hosting discovery](/discover/discovery) / [Frameworks and execution targets](/discover/stack) / [Frameworks](/discover/stack/frameworks) / [Express](/discover/stack/framework-express) / [Configure build and start for Express](/guides/express/build-and-start)
