Getting Started with Supabase Declarative Schema [2026]

Introduction

No matter what platform you are developing with, database migrations can get complex quickly. Early in a project you make many changes to the database schema, which results in a long list of migration files. This complex array of migration files makes it difficult to find the current definition of a table, view or enum. With each new change requiring a new migration file, it can look something like this:

supabase/migrations/
  20240103091412_create_projects.sql
  20240117103055_create_reports_view.sql
  20240215142207_add_project_status.sql
  20240302091733_create_teams.sql
  20240402113045_update_reports_view.sql
  20240518084921_add_project_due_date.sql
  20240607120310_add_teams_billing_fields.sql
  20240701174502_update_reports_view_again.sql

In this article, we will walk through the official Supabase workflow to implement Declarative Schema. It is simple to implement whether you are updating an existing project or starting from scratch.

NOTE: Declarative Schema management with pg-delta is an experimental feature and was only released a few months ago. In my testing, I haven’t run into any issues yet but you should always validate the migrations that are produced.

Even though you are using Declarative Schema, under the hood, Supabase still uses migration files. It’s just that you no longer need to write them yourself. They are automatically generated by the sync command. You can still inspect them but ideally you will never have to modify them directly.

How to Get Started with Declarative Schema

The entire Declarative Schema workflow goes through one command.

supabase db schema declarative sync

Because this is an experimental feature you either have to add this to config.toml

[experimental.pgdelta]
enabled = true

or run with the –experimental flag

supabase db schema declarative sync --experimental

This command compares your current database schema with the existing declarative schema files. If no schema files exist, then it generates them from the existing database. By default, the schema files are written to the database/ folder in your Supabase project. From now on, you’ll make changes to the declarative schema files and let Supabase automatically generate the migration files.

On the first run, the sync command generates the declarative schema files. On subsequent runs, it generates migrations based on the changes to the schema files.

The generated structure looks something like this:

supabase/database
   cluster
   schema
      functions/
      tables/
         clients.sql
         projects.sql
         ...
      views/
      types/

Now instead of searching through migration history, you can easily navigate to the table, function or view you want.

You can reorganize the code into a different file structure but, at least for me, the structure it generates is in a format that I like.

Daily Development Workflow

After the initial setup, every schema change follows the same workflow:

Edit schema file
        ↓
supabase db schema declarative sync
        ↓
Review generated migration
        ↓
Commit both

It’s a good idea to review the generated migration files before committing to ensure the generated SQL matches your intended schema changes. But future schema changes should always be made in declarative files, not by directly editing the migrations.

Conclusion

When I started with Supabase, one of the biggest pain points was manually managing migration files. I had mostly always worked with frameworks where migrations were automatically generated from a schema definition.

Declarative schema brings Supabase closer to that development experience. You still get the auditability of migration files without spending time editing them directly. Although this feature is currently experimental, I expect Declarative Schema to become the preferred workflow for most Supabase projects.

← Back to all posts