drizzle-migrate-neon-http
v0.2.0
Published
Run Drizzle SQL migrations on Neon's serverless HTTP driver — no multi-statement SQL, no local Postgres emulation, no night sweats.
Maintainers
Readme
drizzle-migrate-neon-http
Run Drizzle SQL migrations on Neon's serverless HTTP driver — no multi-statement SQL, no local Postgres emulation, no night sweats.
📚 Full documentation: gtnorbeat.github.io/drizzle‑migrate‑neon‑http — getting started, CLI reference and API docs.
Why does this exist?
@neondatabase/serverless v1+ only works as a
tagged template. You can write sql\SELECT 1``, but you cannot hand it a raw SQL string
with multiple statements:
await sql(`CREATE TABLE users (...); INSERT INTO users (...) ...`);
// 💥 TypeError: "The query function does not support string arguments"That means stock migration runners (which feed the whole migration file to the driver) break on Neon HTTP out of the box. You would need a local Postgres, a TCP tunnel, or Hyperdrive — falling back to the very thing serverless Postgres is supposed to remove.
This package runs real Drizzle migrations over HTTP, one statement at a time.
What it does
- Reads your Drizzle
meta/_journal.jsonto get the ordered migration list - Splits each
.sqlfile into individual statements (string-literal-aware) - Executes them via
sql.query(stmt)— the explicit, string-accepting variant - Skips idempotent
object already existserrors so partially-applied states heal - Records applied files by SHA-256 in
drizzle.__drizzle_migrations - Warns (or fails with
--strict) on.sqlfiles missing from the journal - Ships a CLI (
--dry-run,--dir,--strict,--retries,--timeout) and an importable runner API
Requirements
- Node.js >= 18
- A Drizzle migrations folder, generated with
drizzle-kit generate— the runner readsmeta/_journal.jsonand theNNNN_*.sqlfiles inside the folder - A Neon (or Postgres-compatible) connection string, via the
DATABASE_URLenvironment variable or the--urlflag @neondatabase/serverlessinstalled (peer dependency)
Quick start
npm install -D drizzle-migrate-neon-http @neondatabase/serverless
export DATABASE_URL="postgresql://user:[email protected]/db"
# after running `drizzle-kit generate`
drizzle-migrate-neon-http --dir ./drizzle --dry-run # preview
drizzle-migrate-neon-http --dir ./drizzle # applyHardening for CI:
# Fail fast if a migration file was generated but never registered in the
# journal (it would otherwise be silently skipped).
drizzle-migrate-neon-http --dir ./drizzle --strict
# Retry transient HTTP failures instead of failing the whole run.
drizzle-migrate-neon-http --dir ./drizzle --retries 3
# Give each query a deadline so a stalled connection fails instead of hanging.
drizzle-migrate-neon-http --dir ./drizzle --timeout 15000Programmatic:
import { neon } from "@neondatabase/serverless";
import { runMigrations } from "drizzle-migrate-neon-http";
const sql = neon(process.env.DATABASE_URL);
await runMigrations({
sql,
migrationsDir: "./drizzle",
strict: true,
retries: 3,
timeoutMs: 15000,
});Journal drift — if a
NNNN_*.sqlfile is present but missing frommeta/_journal.json, the runner never applies it (it only walks the journal). By default this is surfaced as a warning;--strictturns it into a hard failure so the mistake is caught in CI rather than as a missing column in production.
Wait — there's more
The docs are hosted at
gtnorbeat.github.io/drizzle-migrate-neon-http
and maintained on the dedicated docs branch:
Contributing
Found a bug? Want a feature? PRs are welcome and appreciated. 🤝
- Read the Contributing Guidelines — setup, conventions and testing in one page
- Use the issue templates to file a bug report or feature request
- Keep PRs small, tested (
npm test) and linted (npm run lint) - Commit messages follow Conventional Commits (
feat:,fix:,docs:…)
License
MIT © astrocat986 — see LICENSE
