Skip to main content
supaschema needs a live database connection to compute diffs, apply migrations, and generate types — it compares your declarative schema files against the actual objects in a running PostgreSQL instance. The environments system gives you a clean way to manage multiple database targets (local, staging, production) without repeating connection strings on every command or leaking credentials into shell history.

Configuring Named Environments

Add an environments key to your supaschema.config.json. Each entry is a name of your choosing mapped to an object with a databaseUrl field:
{
  "environments": {
    "local": {
      "databaseUrl": "postgresql://postgres:postgres@localhost:54322/postgres"
    },
    "staging": {
      "databaseUrl": "postgresql://user:pass@staging-host:5432/mydb"
    }
  }
}
Environment names are arbitrary strings — use whatever naming convention fits your workflow (local, dev, staging, preview, production, or feature-branch names).

Using Named Environments on the CLI

Pass the --env flag followed by the environment name to target a specific database:
# Diff your schema files against the staging database
npx supaschema diff --env staging

# Generate and write migrations using the local database as the source of truth
npx supaschema migrations --env local

# Push the latest migration to staging
npx supaschema push --env staging
Any supaschema command that requires a database connection accepts the --env flag.
Add short npm scripts to your package.json for the environments you use most often:
{
  "scripts": {
    "db:diff": "supaschema diff --env local",
    "db:push:staging": "supaschema push --env staging"
  }
}

URL Resolution Order

When supaschema needs a database URL, it checks the following sources in order, stopping at the first match:
  1. --database-url <url> CLI flag — an explicit connection string passed directly to the command
  2. --env <name> CLI flag — looks up the named environment in supaschema.config.json
  3. SUPASCHEMA_DATABASE_URL environment variable — a connection string set in the shell or CI environment
  4. Supabase auto-discovery — reads supabase/config.toml to discover the local Supabase stack connection details
This order means that an explicit --database-url flag always wins, and the automatic Supabase discovery only fires when no other source is available.

Using the SUPASCHEMA_DATABASE_URL Environment Variable

For CI pipelines and scripts where you do not want to store connection strings in config files, set SUPASCHEMA_DATABASE_URL in the environment:
export SUPASCHEMA_DATABASE_URL="postgresql://user:pass@db-host:5432/mydb"
npx supaschema diff
In a GitHub Actions workflow, inject the URL from a secret:
- name: Diff schema
  run: npx supaschema diff
  env:
    SUPASCHEMA_DATABASE_URL: ${{ secrets.STAGING_DATABASE_URL }}
No --env or --database-url flag is needed when the variable is set.

Supabase Auto-Discovery

If you are working with a local Supabase stack and have not configured any URL, supaschema reads your supabase/config.toml to discover the database connection automatically:
# No flags needed when supabase/config.toml is present and the local stack is running
npx supaschema diff
supaschema extracts the db.port and db.password values from config.toml and constructs the connection string for you. This means a freshly initialized Supabase project works out of the box with zero URL configuration.
Auto-discovery only works with a running local Supabase stack. If the containers are not running, start them with supabase start before running any supaschema commands.

Security Considerations

Never hardcode production database URLs in supaschema.config.json if that file is committed to a shared repository. Anyone with read access to your repo would have access to your production database credentials.
Follow these practices to keep credentials safe:
  • Local development — the default Supabase local connection string (postgres:postgres@localhost:54322) carries no sensitive credentials and is safe to commit.
  • Staging and production — store connection strings in SUPASCHEMA_DATABASE_URL or your CI secret manager (GitHub Actions secrets, Vault, AWS Secrets Manager, etc.) and inject them at runtime.
  • .env files — if you use a .env file to set SUPASCHEMA_DATABASE_URL locally, add .env to .gitignore and provide a .env.example with placeholder values for new contributors.
  • Read-only roles — for commands that only read schema state (like diff in check mode), consider using a read-only database role to limit the blast radius of an accidentally exposed URL.
# .env (gitignored)
SUPASCHEMA_DATABASE_URL=postgresql://user:s3cr3t@prod-host:5432/mydb

# .env.example (committed)
SUPASCHEMA_DATABASE_URL=postgresql://user:password@host:5432/dbname