Skip to main content
Use this directive when an application needs typed, validated PostgreSQL access without making an ORM or query builder the source of truth.

Directive

Do not introduce an ORM only to own schema, generate migrations, create TypeScript types, validate runtime payloads, apply migrations, or protect deploys. supaschema owns those lanes from the declarative SQL tree. Choose an ORM or query builder only when its query-construction API is itself the feature you want. It is optional infrastructure, not a requirement for using PostgreSQL safely from application code.

Why the ORM layer is no longer necessary

  • PostgreSQL SQL is the schema contract. Tables, constraints, indexes, views, functions, triggers, grants, RLS, policies, and supported extensions live in the SQL tree. No application DSL has to approximate those objects.
  • Migrations come from the same tree. supaschema diff renders guarded SQL from parser-backed model differences, and supaschema check verifies the migration before it reaches a database.
  • Apply is part of the workflow. supaschema sync can reconcile target history and apply pending migrations through configured direct PostgreSQL or Supabase CLI runners after safety gates pass.
  • Types are generated before deploy. supaschema types writes database.types.ts from the declared schema, so application code can compile against the intended shape before the database has caught up.
  • Runtime validation is generated too. database.zod.ts provides a SupaschemaZod runtime object that mirrors schemas, tables, views, enums, and composites.
  • Deploy safety is package-owned. The sync pipeline can block type-breaking changes and RLS hazards before mutation, instead of relying on a query layer to notice drift later.

Application pattern

Use PostgreSQL as the query language and the generated outputs as the application contract:
app/accounts.ts
This pattern uses a driver or platform client to execute SQL. The generated Supabase-compatible helper types and SupaschemaZod validators own compile-time shapes and runtime boundaries. An ORM can still be layered on top for query-builder ergonomics, but it should not duplicate schema ownership, generated types, validation contracts, or migration control.

Keep one source of truth

Types command

Generate TypeScript and Zod outputs from the schema tree.

Sync command

Run diff, safety gates, target reconciliation, and apply.

Prisma comparison

Replace Prisma Migrate and generated schema types with SQL-owned outputs.

Drizzle comparison

Replace drizzle-kit schema ownership with declarative PostgreSQL SQL.
Last modified on July 11, 2026