supaschema.config.json file is the single source of truth for how supaschema discovers your schema files, generates migrations, connects to databases, and enforces safety rules. Place it in your project root alongside package.json, and supaschema will pick it up automatically every time you run a command.
Config File Discovery
supaschema resolves its configuration in the following order:--config <path>CLI flag — explicitly point to any config file at an arbitrary path; this always takes precedence and skips auto-discovery entirelysupaschema.config.json— standard JSON config in the project rootsupaschema.config.mjs— ESM module that exports a config object as its default export, tried after.jsonsupaschema.config.js— CJS or ESM module, tried after.mjs- Built-in defaults — if no config file is found, all options fall back to their default values
.mjs or .js config, export your config object as the default export:
Complete Example
Option Reference
$schema
A URL or local path pointing to the supaschema JSON Schema file. Setting this
enables editor autocomplete and validation for all config options. Use
"./node_modules/supaschema/config-schema.json" for a local project
installation.adapter
Controls which schema adapter supaschema uses when diffing your schema files
against a live database.
supabase-auto— automatically excludes Supabase-managed schemas (auth,storage,realtime, etc.) from declarative ownership and blocks accidental changes to them.postgres— plain PostgreSQL mode with no special-cased schemas. Use this for non-Supabase Postgres deployments.
cascade
Cascade mode for destructive operations. This is always
"never" and cannot
be changed — it is a safety invariant that ensures supaschema never silently
cascades drops to dependent objects.destructiveChanges
Governs how supaschema responds when the computed diff contains a destructive
operation such as a column drop, a type change, or a table removal.
hint-required— supaschema blocks the migration and emits a diagnostic code (SUPA_PLAN_DESTRUCTIVE_HINT_REQUIRED) unless you have added the relevant object key tohints.destructive. This is the recommended default.block— supaschema unconditionally blocks all destructive operations. Use this in CI pipelines that should never allow data-loss changes.allow— supaschema renders destructive SQL without requiring hints. Use only in non-production environments where data loss is acceptable.
environments
A map of named environments, each containing a
databaseUrl string. Named
environments let you run supaschema commands against different database
targets without repeating connection strings on the CLI. See the
Environments guide for full details.excludedGrantRoles
A list of role names that supaschema ignores when tracking
GRANT and
REVOKE statements. This prevents supaschema from generating spurious
permission migrations for internal Supabase roles that are managed outside
your schema files.hints.destructive
An array of object key strings that explicitly approve destructive changes on
specific database objects. When supaschema encounters a destructive operation
whose key is present here, it renders a safe
ALTER or DROP … IF EXISTS
instead of blocking. See the Hints guide for key
format details.hints.renames
An array of
{ from, to } pairs that tell supaschema a database object was
renamed rather than dropped and recreated. Each value uses the same
kind:schema.name object key format as hints.destructive. See the
Hints guide for supported rename kinds and
restrictions.idempotency
Idempotency requirement for generated migrations. This is always
"required"
and cannot be changed — supaschema guarantees that every migration it emits
can be safely re-applied without side effects.lockTimeout
The
lock_timeout injected at the top of each migration statement. Accepts
PostgreSQL interval notation: "5s", "500ms", "1min". Keeping this low
prevents long-running migrations from holding locks that block application
queries.managedSchemas
Schemas that supaschema treats as externally managed. Objects inside these
schemas are excluded from declarative ownership and will never appear in the
diff output. When using the
supabase-auto adapter, this list is
automatically populated with Supabase’s platform-owned schemas.You can extend
managedSchemas to exclude third-party schemas (for example,
a timescaledb schema) from supaschema’s ownership model.migrationsDir
The directory where supaschema writes generated migration
.sql files.
Filenames follow the YYYYMMDDHHmmss_<slug>.sql convention. The directory is
created automatically if it does not exist.normalize
Controls SQL normalization applied to schema files before diffing.
deparse— parses SQL into an AST and deparses it back to canonical form, eliminating cosmetic differences between your schema file and the live database.off— disables normalization. Use only when debugging unexpected diff output.
postgresVersion
The target PostgreSQL version. supaschema uses this to gate version-specific
SQL features (for example,
MERGE statements, pg_catalog additions). Accepts
semver-style strings: "14", "15", "15+", "16".renameDetection
Controls how supaschema detects object renames.
hints-only— renames are only recognized when you supply an explicithints.renamesentry. This avoids false-positive rename detection.off— rename detection is fully disabled; drops and additions are always treated as independent operations.
schemaPaths
One or more directories that supaschema scans for schema SQL files. Files are
read in lexicographic order within each directory. You can supply multiple
paths to compose schemas from separate locations.
schemas.include
When non-empty, supaschema only diffs the schemas listed here. All other
schemas in the database are ignored, even if they contain objects not present
in your schema files.
schemas.exclude
Schemas to skip entirely during diffing. Objects inside excluded schemas are
never touched regardless of what is in your schema files.
schemas.include and schemas.exclude are mutually exclusive. Setting both
produces a validation error.statementTimeout
The
statement_timeout injected at the top of each migration statement.
Accepts PostgreSQL interval notation. Raise this value for migrations that
involve large table rewrites; keep it low in OLTP environments to avoid
query starvation.transactionMode
Controls how migration SQL is wrapped in transactions.
per-migration— wraps the entire migration file in a singleBEGIN … COMMITblock. If any statement fails, the whole migration rolls back.per-statement— each statement runs in its own transaction. Use this when your migration contains statements that cannot run inside a transaction (for example,CREATE INDEX CONCURRENTLY).
typesFile
Output path for the generated TypeScript types file. supaschema writes a
fully typed
Database interface here that mirrors your schema. Pass this file
to the Supabase client for end-to-end type safety.zodFile
Output path for the generated Zod validators file. When set, supaschema emits
Zod schemas for every table and view in your schema, ready to use for
runtime validation.
validators
An array of SQL validators that supaschema runs against your schema files
before diffing. Available validators:
Each additional validator must be installed separately and available on your
| Validator | Description |
|---|---|
internal-parser | supaschema’s built-in parser; always runs |
squawk | Squawk linter for migration safety rules |
pgls | PostgreSQL Language Server linting |
sqlfluff | SQLFluff style and syntax linter |
pg-formatter | pg_formatter style checker (runs pg-formatter --check) |
PATH. A configured validator that is not installed produces a
SUPA_VALIDATOR_UNAVAILABLE error — configured checks never silently skip.