Does Supabase Work With TypeORM?
Yes, TypeORM works excellently with Supabase's PostgreSQL database, giving you a type-safe ORM layer with full access to Supabase's auth and realtime features.
Quick Facts
How Supabase Works With TypeORM
TypeORM connects to Supabase exactly like any PostgreSQL database—you point it at your Supabase connection string and define entities normally. Supabase exposes a standard PostgreSQL endpoint, so TypeORM's pg driver handles everything. The real power comes from layering: use TypeORM for your domain models and queries, Supabase Auth for user management via their JavaScript client, and Supabase Realtime by subscribing to PostgREST changes alongside your TypeORM operations. This separation is clean because TypeORM manages your schema and queries while Supabase handles authentication, row-level security (RLS), and real-time subscriptions at the database level. You can even use Supabase's auto-generated PostgREST API for frontend calls while keeping TypeORM for backend logic. The main consideration is that Supabase's RLS policies apply regardless of which client connects, so your TypeORM entities should respect the same permission model you've defined in PostgreSQL.
Best Use Cases
Quick Setup
npm install typeorm pg @supabase/supabase-jsimport { DataSource } from 'typeorm';
import { createClient } from '@supabase/supabase-js';
// TypeORM connection to Supabase PostgreSQL
const AppDataSource = new DataSource({
type: 'postgres',
url: process.env.DATABASE_URL, // Your Supabase connection string
entities: ['src/entities/*.ts'],
migrations: ['src/migrations/*.ts'],
synchronize: false, // Use migrations instead
});
// Supabase client for auth & realtime
const supabase = createClient(process.env.SUPABASE_URL!, process.env.SUPABASE_ANON_KEY!);
// Example: Fetch with TypeORM, subscribe to changes with Supabase
await AppDataSource.initialize();
const userRepo = AppDataSource.getRepository(User);
const users = await userRepo.find(); // Type-safe query
// Real-time subscription
supabase
.channel('public:users')
.on('postgres_changes', { event: '*', schema: 'public', table: 'users' }, console.log)
.subscribe();Known Issues & Gotchas
RLS policies can silently filter results when using TypeORM if the connected user doesn't have permission. Queries return empty instead of errors.
Fix: Always test RLS policies explicitly. Use Supabase's dashboard to verify policies before deploying. Consider using a service role key for admin operations and user-scoped keys for client queries.
TypeORM migrations won't automatically apply Supabase-specific features like RLS policies or the realtime publication flag.
Fix: Write raw SQL migration files in TypeORM for RLS policies. Use Supabase dashboard or custom SQL migrations to enable realtime on tables (ALTER TABLE ... REPLICA IDENTITY FULL).
Connection pooling: Supabase's connection pooler (PgBouncer) in 'transaction' mode can cause issues with TypeORM's long-lived connections in some edge cases.
Fix: Use 'session' mode for pooling, or upgrade to Supabase's newer session pooler. For serverless functions, use Supabase's built-in connection pooler endpoint.
Supabase's JWT auth tokens aren't automatically passed to TypeORM—they're for PostgREST/realtime, not the direct connection.
Fix: Use service role keys or user-scoped keys directly with TypeORM in backend code. Keep user-facing requests through PostgREST if using Supabase client-side auth.
Alternatives
- •Sequelize + Supabase: Another ORM option for PostgreSQL, less type-safe than TypeORM but simpler for quick projects
- •Prisma + Supabase: Modern ORM with auto-generated client, arguably easier DX than TypeORM, excellent for full-stack apps
- •Raw queries + Supabase PostgREST API: Skip the ORM entirely, use Supabase's auto-generated REST API with your own validation layer
Resources
Related Compatibility Guides
Explore more compatibility guides