runMigrations()
import { runMigrations } from "drizzle-migrate-neon-http";Runs every pending migration from a Drizzle journal over a Neon HTTP connection.
Signature
runMigrations(options: {
sql: NeonQueryFunction; // the return of neon(DATABASE_URL)
migrationsDir: string; // path to the drizzle `out` directory
dryRun?: boolean; // default false
log?: { log(msg: string): void; warn?(msg: string): void; error(msg: string): void }; // default console
alreadyApplied?: Set<string>; // pre-seeded hashes (e.g. for tests/tools)
strict?: boolean; // fail on orphaned .sql files (default false — warn)
retries?: number; // extra attempts after a failure, with backoff (default 0)
timeoutMs?: number | null; // per-query deadline in ms (default null — no limit)
}): Promise<void>Behavior
- Creates the
drizzleschema anddrizzle.__drizzle_migrationstracking table (id,hash,created_at) if missing. - Reads
{migrationsDir}/meta/_journal.jsonfor the ordered migration list. - Warns (or throws, with
strict) about any*.sqlfile in the directory that is not registered in the journal — such files are never applied. - For each file not yet applied (by SHA-256):
- splits it with splitStatements
- executes each statement via
sql.query(stmt) - records the file hash in the tracking table
- Skips files already applied (hash match).
Re-runs & healing
Migrations tracked by hash are skipped. If a file was partially applied during a previous failed run, the object already exists codes are skipped so the rest completes (see error codes). Fully-applied files are never re-executed.
With retries > 0, a failed pass is retried from scratch with exponential backoff (1s, 2s, 4s, … capped at 10s). Re-runs re-read the applied hashes, so completed files stay skipped and a partially-applied file heals via the idempotent skips above. With timeoutMs set, each driver call is raced against a deadline — a stalled HTTP request rejects instead of hanging.
Example
import { neon } from "@neondatabase/serverless";
import { runMigrations } from "drizzle-migrate-neon-http";
const sql = neon(process.env.DATABASE_URL);
await runMigrations({
sql,
migrationsDir: "./drizzle",
log: {
log: (m) => console.log(m),
error: (m) => console.error(m),
},
});Errors
The function throws when:
- the journal file is missing or unreadable
- a referenced
.sqlfile is missing - an orphaned
.sqlfile is present andstrictis set - a statement fails with a non-idempotent error (see errors)
- a query exceeds
timeoutMs
Failures abort the file, and the package exits the process with code 1 from the CLI. The tracking table is only written after all statements in a file succeed.
