Web Dev

Supabase Declarative Schemas 2.0 with pg-delta

Supabase shipped Declarative Schemas 2.0 with pg-delta, a new Postgres diff engine that tracks RLS policies, grants, and extension-managed objects that the previous tool missed.

5 min readSource: Supabase Blog

Curated by Kandala Guruprasad. Drafted with AI and checked against the source.

Supabase Declarative Schemas 2.0 with pg-delta

TL;DR

  • Supabase released Declarative Schemas 2.0 on October 2, replacing migra with pg-delta, an open-source Postgres diff tool that now tracks RLS policies, grants, domains, and objects owned by extensions.
  • The new engine reads Postgres system catalogs instead of parsing SQL, eliminating inconsistencies between parser and catalog. Existing projects opt in via a config block; new projects get 2.0 by default.
  • pg-delta generates migrations by loading schema files into shadow databases, diffing them against migration history, and ordering output using a dependency graph built from the catalog.
  • pg-delta is open source under the PostgreSQL License and runs standalone as @supabase/pg-delta on npm, compatible with Postgres versions 14 through 18.
Released
October 2, 2026
CLI requirement
Supabase CLI 2.119 or later
License
PostgreSQL License

What happened

Supabase shipped Declarative Schemas 2.0 on October 2 at Supabase Select. The Supabase CLI now generates migrations using pg-delta, an open-source Postgres diff tool Supabase built and open sourced, instead of migra. The declarative schemas workflow remains unchanged: developers edit SQL schema files under supabase/schemas/, the CLI generates a migration, they review it, and apply it. New CLI projects receive 2.0 by default; existing projects opt in by adding an experimental.pgdelta section to config.toml with enabled = true.

Why pg-delta replaces migra

Migra, the Python tool that powered the original declarative schemas since 2021, had design limitations that grew over time. It could not diff domains, publications, or comments—changes to these objects never appeared in generated migrations, forcing developers to write hand-written migrations to capture them. The tool also could not distinguish between Supabase-managed schema (like the auth schema) and user-owned schema, especially for objects like triggers that reference both. Supabase's own middleware database required dozens of hand-patched migrations for grants and privileges migra did not track. Rather than extend migra further, which would have meant fighting its fundamental design, Supabase built pg-delta from scratch.

The first version of pg-delta powered branch merge diffs in the dashboard from February 2026 and shipped as a public alpha in the CLI in April. After a few months in production, it became clear the design would not scale. Its knowledge of Postgres lived in multiple places: a parser inferred types from SQL text while a separate catalog reader could disagree about what it saw. When the two disagreed, the diff was wrong. In June, Supabase started over with one principle: Postgres is the only source of truth. The new engine never parses SQL. Instead, the CLI loads schema files into shadow Postgres databases, letting a real Postgres instance handle all understanding. By August, the rewrite replaced the original engine everywhere Supabase uses it, including dashboard branch diffs and Realtime schema exports.

What pg-delta now covers

pg-delta emits SQL for tables, columns, constraints, indexes, functions, triggers, and all the objects migra could diff. It also covers RLS policies with full create, drop, and alter support instead of only create and drop. Views now preserve security_invoker settings and are diffed along with their owner and grants. Column privileges, comments, roles, domains, and publication membership all appear in generated migrations. Indexes on materialized views are restored rather than lost when views are recreated. Partitions, publications, subscriptions, and foreign tables are now included.

Objects owned by extensions are handled through their own APIs. pg-delta never emits raw create or drop statements for pg_partman partitions or pgmq queue tables. Instead, it emits calls like select pgmq.drop_queue('q'). The CLI flags these as destructive. When pg-delta encounters unsupported objects, it produces a warning. Passing --strict-coverage turns warnings into errors, which fails CI to ensure nothing is missed. The output is a plain SQL file written to supabase/migrations/. Hand-written migrations continue to work, and once pg-delta is enabled, db diff and db pull also use it.

How to turn on pg-delta

Existing projects require Supabase CLI 2.119 or later. pg-delta ships under the [experimental.pgdelta] section in config.toml. New projects get it by default from supabase init. To enable it on an existing project, add this block to config.toml:

The two shadow databases run in Docker or Podman by default. If experimental stack commands are enabled, they can run on the native runtime instead. Projects that do not add the configuration block continue to use migra, and all existing commands keep working. The next major CLI version will make pg-delta the default for all projects; setting enabled = false will preserve migra for projects that need it.

If a project already uses declarative schemas with migra, expect a catch-up migration on the first supabase db pull after enabling pg-delta. Switch scripts from supabase db diff to supabase db schema declarative sync. The CLI provides fallback flags and config options for reverting to migra if needed.

toml
[experimental.pgdelta]
enabled = true

Workflow: from schema file to migration

The workflow has four steps. First, create a SQL file under supabase/schemas/ with the table definition and policies. Then run supabase db schema declarative sync -f <migration-name> --no-apply to generate the migration file. The CLI diffs schema files against migration history and writes the result to supabase/migrations/. Next, review the migration and apply it locally and to the linked project with supabase start, supabase migration up, and supabase db push. Pay attention to anything the CLI flags as destructive. pg-delta prioritizes coverage and correctness over producing the least destructive migrations; a renamed column appears as a drop followed by an add, which would lose data. Hand-rewrite flagged statements before applying. Finally, edit the schema file, add columns or policies, and run sync again. The new migration contains only the delta.

When editing views and functions, the advantage is clear: the pull request diff of the schema file shows only changed lines, while the generated migration still carries the full definition. If starting from an existing database with no schema files, run supabase db schema declarative generate --linked to export one SQL file per object under supabase/schemas/, grouped by database schema. If the project has no migration history, run supabase db pull first so sync has a baseline. The same edit-sync-review-apply loop then applies.

bash
supabase db schema declarative sync -f create_profiles --no-apply
bash
supabase db schema declarative generate --linked

Using pg-delta standalone

pg-delta is open source under the PostgreSQL License at supabase/pg-delta on GitHub. It ships on npm as @supabase/pg-delta and installs a pgdelta command-line tool. It runs against any two Postgres databases from version 14 through 18, not just Supabase projects. Use plan to compute the migration between two databases and render to write it out as SQL. pg-delta is still in alpha; breaking changes can ship between releases and larger architectural changes are not ruled out before stable release. If a generated migration looks wrong, open an issue or submit a support ticket with the schema that produced it.

bash
npx @supabase/pg-delta@alpha plan --source "$SOURCE_URL" --desired "$DESIRED_URL" --out plan.json
npx @supabase/pg-delta@alpha render --plan plan.json --out migration.sql

Source

Supabase Bloghttps://supabase.com/blog/declarative-schemas-2-0-pg-delta

AI-assisted, verified against the source. This post was drafted with AI from the primary source linked above and checked automatically against it. For anything you depend on, read the original.

  • #supabase
  • #postgres
  • #migrations
  • #pg-delta
  • #schema

More in Web Dev