# Can I use Drizzle or Prisma without supabase-js?

> On Business and Enterprise, yes, through the SSH tunnel. On other plans, ORMs can't connect at runtime, but you can still use them to define your schema and generate SQL migrations.

Source: https://supahost.app/kb/orm-without-supabase-js · Updated 2026-11-11

It depends on your plan. Drizzle and Prisma talk to Postgres over a direct connection. On SupaHost that connection only exists on Business and Enterprise, through an SSH tunnel to `127.0.0.1:5432`. On Builder and Pro, an ORM can't connect to your project. You can still use it to model your schema and generate SQL migrations, then query at runtime with supabase-js.

## Option 1: schema and migrations with the ORM, queries with supabase-js (any plan)

Many teams like an ORM for its schema file and migration generator more than for its query API. That part works on every plan, because the output is plain SQL.

With Drizzle:

```ts
// db/schema.ts
import { pgTable, uuid, text, integer, timestamp } from 'drizzle-orm/pg-core'

export const recipes = pgTable('recipes', {
  id: uuid('id').primaryKey().defaultRandom(),
  ownerId: uuid('owner_id').notNull(),
  title: text('title').notNull(),
  servings: integer('servings').default(2),
  createdAt: timestamp('created_at', { withTimezone: true }).defaultNow(),
})
```

```bash
npx drizzle-kit generate   # writes SQL files to ./drizzle
```

Apply the generated SQL in Studio's SQL editor, or have your AI tool send it with the MCP `apply_migration` tool, which records each migration in `supabase_migrations.schema_migrations`. Prisma works the same way: `prisma migrate diff` with `--script` prints the SQL for a schema change.

Remember to add RLS in the same migration, since ORMs don't generate policies by default:

```sql
alter table public.recipes enable row level security;
create policy "owners manage recipes" on public.recipes
  for all to authenticated
  using ((select auth.uid()) = owner_id)
  with check ((select auth.uid()) = owner_id);
```

At runtime, query with supabase-js. The MCP `generate_typescript_types` tool gives you types for typed results.

## Option 2: the ORM at runtime (Business and Enterprise)

Open the tunnel from the machine running your code and point the ORM at it:

```bash
ssh -N -L 6543:127.0.0.1:5432 supahost@acme.supahost.space
```

```bash
DATABASE_URL="postgresql://postgres:<password>@127.0.0.1:6543/p_app_one"
```

This suits migrations from your laptop or CI, scripts, and long-running servers that can keep a tunnel open (you run and watch it yourself). It doesn't suit serverless platforms, which can't hold an SSH tunnel. Note that the ORM connects as `postgres`, which owns your tables and so isn't filtered by your RLS policies. Access control is up to your code.

## FAQ

### Does Prisma work with SupaHost on Vercel?

Not at runtime: Vercel Functions can't reach a SupaHost project's Postgres. Use supabase-js there, and keep Prisma for schema and migration generation if you like.

### Do I need a pooler connection string for Prisma?

No pooler exists on SupaHost. Through the tunnel you connect straight to Postgres, which has 400 connections shared by all projects on the instance, so keep the ORM's pool small.

### Can drizzle-kit push or migrate directly?

On Business, yes, through the tunnel. On other plans, use `drizzle-kit generate` and apply the SQL yourself.

## Related

- [Drizzle ORM](/docs/integrations/drizzle)
- [Prisma](/docs/integrations/prisma)
- [SQL migrations](/docs/database/migrations)
- [Common Prisma errors with Supabase](/kb/prisma-errors)
