Skip to content

Deployment

Use jsorm deploy as the production-safe migration entrypoint. Keep request-time runtime code separate from schema ownership, and run deploys from a controlled Node.js environment.

| Package/runtime | Use it for | Do not use it for | |-----------------|------------|-------------------| | @jsorm/runtime + @jsorm/fetch | Edge-safe request handlers and fetch-based SQL access | Owning migrations or jsorm deploy | | @jsorm/core / @jsorm/node + native adapters | Node services, release jobs, direct database access | Edge isolates without TCP/native binary support | | @jsorm/node | CLI, migrations, jsorm deploy, release automation | Edge request handling |

jsorm deploy is intentionally Node-only deployment ownership. Even if the app runs on Vercel Edge or Cloudflare Workers, deploys should run in CI, a release job, or a dedicated container with @jsorm/node.

Terminal window
jsorm deploy [selector] [--dry-run] [--verbose] [--strict] [--force]

jsorm deploy:

  1. validates connectivity
  2. checks applied migration hashes/checksums
  3. inspects pending migrations for unsafe changes
  4. verifies schema snapshot integrity before execution
  5. applies pending migrations, or previews them with --dry-run
  6. verifies schema snapshot integrity again after execution

When jsorm.config.ts defines a default migration source, selector mode is optional:

Terminal window
pnpm exec jsorm deploy --strict --verbose
pnpm exec jsorm deploy main --strict

| Flag | Meaning | Typical use | |------|---------|-------------| | --dry-run | Preview pending deploy plan without mutating migration history | CI validation and pre-release review | | --verbose | Print issues and compiled SQL statements | Release logs and troubleshooting | | --strict | Fail on warnings, snapshot drift, or review-required changes | Default for CI and production | | --force | Allow destructive migrations that are blocked by default | Only after explicit review |

jsorm deploy is designed for CI/CD decisions:

| Exit code | Meaning | CI interpretation | |-----------|---------|-------------------| | 0 | Success | Promote release | | 2 | Usage/CLI error | Fix command/config | | 3 | Connectivity/preflight failure | Retry infra or secrets setup | | 4 | Integrity failure | Stop release and investigate drift/checksums | | 5 | Unsafe deploy blocked | Require review or --force | | 6 | Execution/verification failure | Stop rollout and inspect database state |

Recommended release commands:

Terminal window
# preview in CI
pnpm exec jsorm deploy --dry-run --strict --verbose
# production release
pnpm exec jsorm deploy --strict --verbose
  1. Build artifacts.
  2. Run jsorm deploy --dry-run --strict --verbose in CI.
  3. Run jsorm deploy --strict --verbose in the release job.
  4. Only then promote the new app version.

This keeps migration ownership in Node, keeps edge bundles minimal, and gives CI explicit failure signals.

name: deploy
on:
push:
branches: [main]
workflow_dispatch:
jobs:
migrate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
with:
version: 11
- uses: actions/setup-node@v4
with:
node-version: 24
cache: pnpm
- run: pnpm install --frozen-lockfile
- run: pnpm run build
- run: pnpm exec jsorm deploy --strict --verbose
env:
DATABASE_URL: ${{ secrets.DATABASE_URL }}
  • Node runtime: use @jsorm/core or @jsorm/node with native adapters and pin handlers when needed:
export const runtime = 'nodejs';
  • Edge runtime: use @jsorm/runtime + @jsorm/fetch in the app bundle.
  • Run pnpm exec jsorm deploy --strict --verbose in GitHub Actions or another Node release step, not inside the edge function.
  • Use @jsorm/runtime + @jsorm/fetch for request-time access.
  • Run deploy separately from a Node job before publishing the Worker.
Terminal window
pnpm exec jsorm deploy --strict --verbose
pnpm exec wrangler deploy

Run deploy before app startup, or move it into a one-off init container:

FROM node:24-alpine AS build
WORKDIR /app
COPY . .
RUN corepack enable && pnpm install --frozen-lockfile && pnpm run build
FROM node:24-alpine
WORKDIR /app
COPY --from=build /app ./
RUN corepack enable
CMD ["sh", "-c", "pnpm exec jsorm deploy --strict --verbose && pnpm start"]

Use a Node deploy job with @jsorm/pg against the Postgres connection string:

Terminal window
pnpm exec jsorm deploy main --strict --verbose

If the app runtime is edge-only, keep runtime traffic on @jsorm/runtime + @jsorm/fetch, but keep deploy on Node.

  • Deploy/migrations: Node job + @jsorm/pg
  • Edge request path: @jsorm/runtime + @jsorm/fetch when you expose HTTP SQL access
Terminal window
pnpm exec jsorm deploy --strict --verbose

Use a Node deploy job with @jsorm/mysql:

Terminal window
pnpm exec jsorm deploy main --strict --verbose

For edge request traffic, keep a separate HTTP/fetch access path. Do not expect the native MySQL adapter to run inside edge isolates.