Migration Preview

Reads a Postgres migration back step by step with what each step locks and what can't be undone, so it doesn't take production down or lose data.

StopsHelps prevent a migration locking a production table for hours

Installation

pnpm dlx shadcn@latest add https://bollard-ui.vercel.app/r/migration-preview.json

The files land in your project. They're yours to edit.

Usage

migration-preview-usage.tsx
import { MigrationPreview } from "@/components/ui/migration-preview"

return <MigrationPreview label="20261014_add_order_region.sql" defaultValue={migration} tableSizes={{ orders: 12_400_000, customers: 86_000 }} />

What it catches

  • Locks each step takes and what other sessions can't do meanwhile
  • Steps that rewrite or scan every row of a large table (from tableSizes)
  • Dropped tables and columns that can't be undone
  • NOT NULL without a default on existing rows, and renames that break running code
  • CREATE INDEX CONCURRENTLY inside a transaction, and missing lock_timeout

Props

MigrationPreview props
PropTypeDefault
value

Controlled migration SQL (Postgres).

string—
defaultValue

Initial SQL when uncontrolled.

string""
onValueChange

Called with the new SQL when a fix is applied or undone.

(value: string) => void—
locale

Number format for row counts.

string—
label

Visible label; shorthand for `messages.label`.

string—
messages

Every visible string (`_one` keys are the singular forms). `{count}`, `{n}`, `{rows}`, `{detail}` are filled in.

Partial<MigrationPreviewMessages>—

* required. Also accepts the native props of <section> (className, aria-*, data-*…), passed through to it.

Accessibility

  • Section labelled by its title; summary uses role=status
  • Each step is labelled with its number; icons are aria-hidden
  • Fix and undo are buttons, and focus moves to Undo after a fix

Only what the source does. Test with your own screen reader and content before shipping.

Limitations

This is a UX guard rail. Enforce on the server: Run migrations with lock_timeout and statement_timeout, test on a production-sized copy, and keep a rollback plan.

  • Postgres only, and lock behaviour can differ between versions
  • A static read: it doesn't run the SQL or know current load
  • Row counts only if you pass tableSizes

What it stops

Helps prevent a migration locking a production table for hours

Also known as

db migration · postgres · alter table · lock_timeout · create index concurrently · prisma migrate · drizzle · sql preview

Field type

Dependencies

Pairs well with