Skip to main content
supaschema is best when you want deterministic PostgreSQL or Supabase migrations from declarative SQL files without Docker, a shadow database, or a hand-edited generated migration. The Supabase CLI remains a supported runner for Supabase projects; supaschema apply can also own the guarded apply pipeline through configured direct PostgreSQL or Supabase CLI targets.

Short answer

Use supaschema when the schema files are the source of truth and you need a fast, replay-safe migration from those files. Use supaschema types for generated contracts and supaschema apply for deploy safety gates, target reconciliation, and apply. Keep supabase db push when you want the Supabase CLI to remain the standalone apply step.

Comparison

Why the workflow is different

supaschema parses SQL with PostgreSQL’s parser compiled to WebAssembly. It compares the resulting parse trees and renders a guarded migration from the structural difference. That means it can compare a declared target schema against a git ref, a directory, a dump, a catalog snapshot, or a read-only live catalog without creating a temporary database. Supabase also documents a declarative workflow in which SQL files under supabase/schemas are the source of truth. That narrows the source-model difference; the remaining contrast is execution, replay safety, generated contracts, and apply policy. Supabase’s documented declarative/local flow creates a shadow database, while supaschema’s file path parses and plans in-process. The practical loop is:
diff writes the migration. check catches replay-safety and lock hazards. types regenerates TypeScript and Zod outputs from the schema tree. verify can apply the migration twice in disposable databases and confirm the result matches the declared target. apply applies pending migrations through a configured direct PostgreSQL or Supabase CLI runner. supabase db push remains valid when the Supabase CLI is intentionally kept as the external apply step.

RLS policy safety

Row Level Security policies are tenant boundaries in many Supabase applications. If a policy changes from a broad predicate to a tenant-scoped predicate, the migration generator must see the body change, not just the policy name. supaschema models policy expressions and surfaces predicate changes as first-class operations. That makes RLS policy changes visible in review and CI.

Benchmark results

The 2026-07-21 repository benchmark run compares supaschema 0.4.3 with all five Supabase CLI 2.109.1 diff engines on identical fixtures. At 1,000 tables, supaschema measured 2.08-2.53s while the engines measured 38.7-57.7s; at 2,500 tables, the medians were 4.71-5.80s versus 268-352s. The run used a disposable PostgreSQL 17.6 stack, one warmup per cell, three measured iterations through XL, and one at XXL. It retains four measured Supabase command failures rather than replacing individual rows; no supaschema row failed. See benchmarks for latency, accuracy, and replay-safety charts, and see the anilize case study for a production Supabase schema with thousands of objects.
Last verified 2026-07-21 against the Supabase CLI documentation and CLI 2.109.1. db diff supports declarative SQL files plus explicit database targets; the documented declarative and local workflows use a shadow database. Supabase CLI behavior is set by Supabase and can change, so confirm current command semantics before relying on it.

When to use each tool

Choose supaschema for:
  • Declarative schema repositories where SQL files are the source of truth.
  • CI gates that need to detect drift and prove replay safety.
  • Supabase projects where a shadow or database-backed generation step is slow or unavailable.
  • Teams that want TypeScript and Zod output before applying a migration.
  • Projects where RLS policy changes need explicit review.
Keep using the Supabase CLI directly for:
  • Applying the final migration outside the supaschema apply lane.
  • Managing Supabase platform resources outside the schema migration file.
  • Existing deployment workflows that already call supabase db push.

Minimal migration pipeline

Install with the package-manager lane from Installation. Add supaschema verify before merge when CI can reach a disposable PostgreSQL database.

Sources

Last modified on July 24, 2026