
Se hai cercato "supabase vs drizzle" aspettandoti un vincitore, ecco la sorpresa: non esiste, perché Supabase è un backend Postgres (un Backend-as-a-Service) e Drizzle è un ORM TypeScript che gira sopra una connessione al database — inclusa quella di Supabase. Vivono su livelli diversi del tuo stack, quindi non competono davvero. Non preoccuparti, è più semplice di quanto sembri.
TL;DR: Usa Supabase per il backend (database, auth, storage, realtime). Aggiungi Drizzle se vuoi SQL type-safe sulle query più complesse. La maggior parte delle app in produzione finisce per usarli entrambi — pensa "casa e cassetta degli attrezzi," non "casa o cassetta degli attrezzi."
Supabase vs Drizzle in sintesi
Ecco il confronto fianco a fianco che la maggior parte delle pagine "vs" salta. Nota quanto poco si sovrappongono — è proprio questo il punto.
| Dimensione | Supabase | Drizzle |
|---|---|---|
| Cos'è | Backend-as-a-Service Postgres | ORM TypeScript / query builder |
| Livello | Piattaforma backend | Libreria di accesso ai dati |
| Database | Postgres gestito | Si connette a qualsiasi Postgres (incluso Supabase) |
| Auth / Storage / Realtime | Sì (integrati) | No (fuori scope) |
| Query type-safe | Parziale (tipi generati) | Sì (in prima classe, inferiti) |
| Migrazioni | SQL editor / CLI | drizzle-kit (schema-as-code) |
| Edge / serverless | Edge Functions (Deno) | ~7.4 kb, edge-native |
| Prezzi | Gratis / $25 / $599 | Gratis (open-source) |
| Veri concorrenti | vs Firebase, altri BaaS | vs Prisma, altri ORM |
Vedi quanto le righe si sovrappongono poco? Supabase risponde a "dove vive la mia app?"; Drizzle risponde a "come la interrogo in TypeScript?" Sia che tu cerchi supabase vs drizzle o drizzle vs supabase, questa differenza orienta ogni decisione qui sotto.
Cos'è davvero Supabase
Supabase è un backend Postgres gestito che raggruppa quasi tutto ciò di cui un'app tipica ha bisogno fin dal primo giorno. BaaS — Backend-as-a-Service — significa che ottieni un vero backend (database più servizi) senza dover configurare server. La parola chiave è vero: sotto il cofano c'è PostgreSQL genuino, non un'astrazione proprietaria da cui non puoi scappare in seguito.
Ecco cosa ottieni subito:
- Auth — email/password, magic link, social login, SSO, passwordless.
- Storage — archiviazione file S3 con policy Row Level Security e trasformazioni immagine.
- Realtime — ascolto dei cambiamenti del database, presence e canali broadcast.
- Edge Functions — funzioni TypeScript su Deno, distribuite globalmente.
- REST API automatica via PostgREST (trasforma le tue tabelle in un'API REST istantanea) più GraphQL tramite
pg_graphql. - Supporto Vector per gli embedding, così le funzionalità AI hanno una casa.
Il modo predefinito per parlare a tutto questo dalla tua app è supabase-js, la libreria client ufficiale. Gestisce letture e scritture del database (instradate tramite PostgREST), sessioni auth, sottoscrizioni realtime e upload di file — un solo client per l'intera piattaforma. Se stai valutando i backend in primo luogo, la nostra analisi completa di Supabase vs Firebase copre quella parte della decisione nel dettaglio.
Cos'è davvero Drizzle
Drizzle è un ORM TypeScript leggero e query builder. Un ORM (object-relational mapper) è una libreria che ti permette di scrivere query al database nel tuo linguaggio di programmazione invece di stringhe SQL grezze — ma Drizzle mantiene le cose vicine all'SQL, quindi non combatti mai con un'astrazione pesante.
Cosa lo distingue:
- Impronta minima — circa 7.4 kb min+gzip con zero dipendenze esterne, il che lo rende edge-native.
drizzle-kit— la CLI che gestiscegenerate,migrateepull(introspezione di un database esistente in TypeScript).- Drizzle Studio — un browser visuale gratuito del database per lo sviluppo locale.
- Inferenza dei tipi — definisci il tuo schema una volta in TypeScript e i risultati delle query sono completamente tipizzati automaticamente.
- Multi-database — funziona con Postgres, MySQL, SQLite e altro.
- Completamente open-source — costa $0.
Ora, la parte importante: Drizzle non è un backend — niente auth, niente storage, niente realtime, niente API server. Fa esattamente una cosa: parlare a un database in modo type-safe. Chiamarlo "ORM" risponde alla ricerca comune "supabase orm" — Supabase non include un ORM pesante di suo, quindi le persone ricorrono a Drizzle (o Prisma) quando ne vogliono uno.
supabase-js vs Drizzle: la stessa query, scritta in entrambi i modi
La differenza tra supabase-js e Drizzle: supabase-js è il client completo della piattaforma (database via PostgREST, più auth, realtime e storage), mentre Drizzle è un ORM Postgres type-safe che fa solo ed esclusivamente query al database. Per renderlo concreto, ecco la stessa identica query — "ottieni i post pubblicati con il loro autore" — scritta prima in supabase-js, poi in Drizzle.
Prima, la versione supabase-js (PostgREST):
import { createClient } from "@supabase/supabase-js";
const supabase = createClient(SUPABASE_URL, SUPABASE_ANON_KEY);
// Get published posts with their author
const { data, error } = await supabase
.from("posts")
.select("id, title, author:authors(name)")
.eq("published", true);
if (error) throw error;
// data: { id, title, author: { name } }[]Ora la versione Drizzle della stessa identica query:
import { drizzle } from "drizzle-orm/postgres-js";
import { eq } from "drizzle-orm";
import postgres from "postgres";
import { posts, authors } from "./schema";
const client = postgres(DATABASE_URL, { prepare: false });
const db = drizzle(client);
// Get published posts with their author
const data = await db
.select({
id: posts.id,
title: posts.title,
authorName: authors.name,
})
.from(posts)
.innerJoin(authors, eq(posts.authorId, authors.id))
.where(eq(posts.published, true));
// data is fully typed from your schema — no codegen stepNoti la differenza nel feeling? supabase-js usa il chaining PostgREST — .from().select().eq() — ed esprime i join tramite quella sintassi stringa annidata author:authors(name), che si legge benissimo per strutture semplici. Drizzle si legge come SQL con superpoteri TypeScript: join espliciti, condizioni esplicite e il tipo del risultato è inferito direttamente dal tuo schema senza nessun passaggio separato di generazione dei tipi.
Nessuno dei due è "migliore" in assoluto: la query supabase-js è più corta e viene con la piattaforma, mentre la query Drizzle offre sicurezza a compile-time sul join e diventa più chiara man mano che le query si complicano — tre join, filtri condizionali, aggregazioni. Questo è il vero trade-off.

Hai davvero bisogno di Drizzle con Supabase? (framework decisionale)
No, di solito non hai bisogno di Drizzle con Supabase — supabase-js porta la maggior parte delle app in produzione da solo. Aggiungi Drizzle solo quando vuoi type safety a compile-time su query complesse o un bundle edge più piccolo. Prima di aggiungere una dipendenza, passa attraverso questa matrice decisionale onesta.
Resta con supabase-js quando:
- Ti affidi a sottoscrizioni realtime, operazioni su file/storage o flussi auth.
- Le tue query sono per lo più CRUD semplici.
- Vuoi un unico client per tutta l'app.
- Stai prototipando e vuoi velocità massima.
Aggiungi Drizzle quando:
- Hai join o aggregazioni complesse che diventano scomode nella sintassi PostgREST.
- Vuoi type safety a compile-time su SQL quasi grezzo.
- La dimensione del bundle conta perché stai deployando su edge o serverless runtime.
- Preferisci migrazioni schema-as-code che puoi revisionare in una pull request.
Usa entrambi (l'esito più comune) quando:
- Vuoi
supabase-jsper auth, storage e realtime, più Drizzle per le query dati pesanti.
| La tua esigenza | Usa |
|---|---|
| Realtime, storage, CRUD veloce, auth | supabase-js |
| Join complessi, SQL type-safe, dimensione bundle edge | Drizzle |
| Un SaaS tipico in produzione | Entrambi |
Pro tip: Inizia con
supabase-js. Passa a Drizzle quando una query diventa davvero problematica — non prima. Aggiungere un ORM prematuramente è una cosa reale, e aggiunge solo configurazione che non ti serve ancora.
Se stai delineando un intero stack più che una singola query, la nostra guida su come scegliere il tech stack SaaS giusto mostra come la decisione su backend e ORM si inserisce nel quadro più ampio.

Come usare Supabase e Drizzle insieme (la configurazione corretta)
Sì, puoi usare Supabase e Drizzle insieme — e la maggior parte dei team in produzione lo fa. Mantieni supabase-js per auth, storage e realtime, poi punta Drizzle sulla stessa connessione Postgres di Supabase per query dati type-safe. Alcuni dettagli di correttezza fanno inciampare le persone, però, quindi mettiamoli tutti a posto in un posto solo.
Installazione e connessione (il driver postgres-js)
Installa i tre pacchetti di cui hai bisogno:
npm install drizzle-orm postgres
npm install -D drizzle-kitPoi connettiti usando il driver postgres-js e passa il client a Drizzle:
import { drizzle } from "drizzle-orm/postgres-js";
import postgres from "postgres";
// prepare: false is REQUIRED with Supabase's transaction pooler
const client = postgres(process.env.DATABASE_URL!, { prepare: false });
export const db = drizzle(client);Quel flag prepare: false non è opzionale — continua a leggere, perché è il motivo più comune per cui una configurazione Supabase + Drizzle si rompe.
Pooler vs connessione diretta: quale stringa usi?
Supabase ti fornisce due stringhe di connessione, e quella giusta dipende dal tuo runtime:
- Pooler (porta 6543, modalità transaction) — usala per funzioni serverless e edge. Ogni invocazione è di breve durata, quindi vuoi una connessione pooled che viene distribuita per transazione.
- Connessione diretta (porta 5432) — usala per server a lunga esecuzione che mantengono una connessione aperta.
Scegli quella sbagliata e o esaurisci le connessioni (diretta su serverless) o aggiungi overhead inutile. Il pooler è anche esattamente ciò che rende necessario il prossimo problema.
Il problema con prepare: false
Hai bisogno di prepare: false perché il pooler in modalità transaction di Supabase non supporta le prepared statement, che il driver postgres-js di Drizzle usa per default. Metti insieme questi due fatti e, senza il flag, le tue query generano errori nel momento in cui passano per il pooler — che su serverless è sempre.
In produzione questa è la riga che fa cadere le persone: tutto funziona contro una connessione diretta in locale, poi ogni query fallisce dopo il deploy su Vercel o una Supabase Edge Function. La correzione è un solo flag:
const client = postgres(DATABASE_URL, { prepare: false });Attenzione: Se le tue query Drizzle funzionano in locale ma si rompono in deployment, controlla prima questo flag. Nove volte su dieci è quello.
Mantenere RLS intatto
Row Level Security (RLS) è una delle migliori funzionalità di Supabase, e non devi rinunciarci per usare Drizzle — ma devi essere deliberato. Esistono due tipi di client:
- Un client admin che usa la chiave service-role bypassa completamente RLS. È potente e pericoloso — tienilo strettamente lato server, mai vicino al browser.
- Un client che rispetta RLS avvolge ogni query in una transazione che imposta il contesto auth Postgres (il ruolo e i claims dell'utente corrente) così le tue policy RLS esistenti si applicano esattamente come farebbero tramite
supabase-js.
Ecco la forma di una query che rispetta RLS — imposta il contesto auth, poi esegui la query Drizzle all'interno della stessa transazione:
import { sql } from "drizzle-orm";
async function rlsQuery(userJwtClaims: { sub: string; role: string }) {
return db.transaction(async (tx) => {
// Tell Postgres who's asking, so RLS policies kick in
await tx.execute(
sql`select set_config('request.jwt.claims', ${JSON.stringify(
userJwtClaims
)}, true)`
);
await tx.execute(sql`set local role authenticated`);
// This query now runs under the user's RLS policies
return tx.select().from(posts);
});
}Drizzle include anche una API RLS nativa e un import drizzle-orm/supabase con i ruoli predefiniti di Supabase (authenticated, anon), rendendo le policy schema-as-code più pulite. Il punto fondamentale: mantieni RLS attivo in Supabase, e lascia che il tuo client Drizzle compatibile con RLS lo rispetti.
Dovresti disattivare la Data API / PostgREST?
Solo se fai query esclusivamente tramite Drizzle. Supabase ti permette di disabilitare la Data API (PostgREST) nelle impostazioni API, il che riduce la tua superficie d'attacco. Ma se qualsiasi parte della tua app usa ancora supabase-js per i dati — e di solito lo fa, per realtime o letture veloci — lascia PostgREST attivo. Non c'è alcuna penalità nel tenerlo.
Se la tua app vive in Next.js (un abbinamento molto comune qui), la nostra guida su come scegliere la configurazione Next.js giusta copre il lato routing e rendering che avvolge questo livello dati.
Configurare Drizzle + Supabase con RLS e pooling correttamente fa inciampare molti team. Hai bisogno di un secondo parere sul tuo backend? Richiedi una consulenza gratuita →
Edge e serverless: dove Drizzle eccelle
Se stai deployando sull'edge, è qui che Drizzle guadagna il suo posto. Con circa 7.4 kb e zero binari nativi, si inserisce nei runtime vincolati dove gli ORM più pesanti faticano — Cloudflare Workers, Vercel Edge, AWS Lambda e persino le Supabase Edge Functions su Deno.
Perché la dimensione conta così tanto qui? Le funzioni edge sono penalizzate da cold start e limiti di bundle, quindi una libreria leggera e priva di dipendenze significa cold start più veloci e bundle che effettivamente rientrano nei limiti. supabase-js funziona anche sull'edge, ma per l'accesso puro ai dati, l'impronta di Drizzle è difficile da battere.
Un paio di cose da tenere a mente sull'edge:
- Usa la stringa di connessione del pooler in modalità transaction (con
prepare: false). - Mantieni la logica delle query leggera così la funzione rimane piccola e veloce.
Il runtime su cui esegui il deploy condiziona anche questo — la nostra analisi su dove fare il deploy delle tue edge function confronta le piattaforme così puoi abbinare il tuo livello dati all'host giusto.
Migrare da supabase-js a Drizzle senza una riscrittura
Hai già rilasciato con supabase-js e ora vuoi Drizzle per alcune query complicate? Buone notizie: non hai bisogno di una riscrittura completa. Puoi eseguire entrambi nello stesso file. Ecco il percorso incrementale che i team usano davvero.
- Lascia
supabase-jsesattamente dove si trova — auth, storage, realtime e il CRUD semplice che gestisce già bene. Non toccarlo. - Introspetta il tuo schema esistente in TypeScript così Drizzle conosce le tue tabelle (incluso il riferimento allo schema
authse ne hai bisogno):
npx drizzle-kit pull- Aggiungi il client Drizzle accanto al tuo client Supabase esistente — stesso database, seconda connessione, con
prepare: falsegià incluso. - Migra una query pesante alla volta. Scegli il tuo join o aggregazione più doloroso, riscrivi solo quello in Drizzle, e rilascialo.
- Lascia tutto il resto su
supabase-js. Non c'è nessun premio per convertire query che funzionavano già bene.
Tranquillo: Puoi chiamare
supabase-jse Drizzle nella stessa funzione. Niente ti obbliga a scegliere globalmente — migra al ritmo che ha senso.
Riscrivere le query a mano è la parte lenta, ed è esattamente il tipo di lavoro meccanico che gli agenti AI di coding che velocizzano questo processo gestiscono bene — punta uno di loro su una query PostgREST e fagli abbozzare l'equivalente Drizzle da revisionare.
Prezzi nel 2026: quanto costa davvero ciascuno
Drizzle è gratuito — è completamente open-source, quindi costa $0. Supabase ha un piano gratuito, poi piani a pagamento a $25/mese (Pro) e $599/mese (Team) nel 2026. Quindi l'unico conto che paghi per questo stack è Supabase; aggiungere Drizzle non costa nulla.
| Piano | Supabase | Drizzle |
|---|---|---|
| Gratis | $0 (500 MB DB, 50k MAU; si mette in pausa dopo 1 settimana di inattività, limite 2 progetti) | $0 — completamente open-source |
| Pro | $25/mese + utilizzo (8 GB DB, 100k MAU, $10 credito compute) | — (gratuito) |
| Team | $599/mese (SOC2/ISO, backup 14 giorni, supporto prioritario) | — (gratuito) |
| Enterprise | Custom (HIPAA, BYO cloud) | — (la versione B2B incorporabile di Studio è l'unica parte a pagamento) |
Drizzle è $0 e completamente open-source (Drizzle Studio incluso), quindi il tuo unico costo del livello dati è Supabase — l'ORM va a bordo gratuitamente.
Un avvertimento: il piano gratuito di Supabase mette in pausa i progetti dopo una settimana di inattività e ti limita a due — ottimo per i prototipi, ma vorrai il Pro per qualcosa di reale. Se sei attento ai costi e stai costruendo in modo snello, la nostra raccolta di strumenti che valgono davvero per le startup mantiene la stessa prospettiva pragmatica.
E Prisma?
Il seguito naturale: se vuoi un ORM, perché Drizzle e non Prisma? Entrambi funzionano perfettamente con Supabase, quindi questo è un confronto equo — a differenza di Supabase vs Drizzle.
- Drizzle — ~7.4 kb, edge-native, sintassi SQL-like, più giovane ma in rapida crescita (circa 900k download npm settimanali). Ideale quando dimensione del bundle e runtime edge contano.
- Prisma — più pesante, ma con una developer experience notoriamente fluida e una adozione più ampia (circa 2,5M download settimanali). Ideale su server tradizionali a lunga esecuzione dove il bundle non è un vincolo.
(Considera quei numeri come approssimativi — cambiano costantemente.) Il riassunto onesto: scegli Drizzle per edge/dimensione bundle, scegli Prisma per ergonomia su un server tradizionale. Entrambi si collegano a una connessione Postgres di Supabase senza problemi.
Come lavoriamo in Techsy
In Techsy rilasciamo app testate in produzione su Supabase, Next.js e PostgreSQL ogni giorno, quindi questa non è un'opinione basata solo sulla documentazione. Il nostro approccio predefinito: supabase-js** per le funzionalità della piattaforma** (auth, storage, realtime) e Drizzle sui percorsi dati intensivi dove la type safety e i join complessi ripagano — RLS sempre attivo, prepare: false incluso dalla prima riga.
E onestamente? Molti progetti che rilasciamo non hanno mai bisogno di Drizzle. Se un'app è per lo più CRUD con realtime, supabase-js da solo è la risposta più pulita — e te lo diremo invece di aggiungere una dipendenza per il gusto di farlo.
Vuoi un secondo parere sul tuo backend Supabase — schema, RLS e configurazione della connessione inclusi? Parla con il nostro team →
Domande frequenti
Drizzle è un sostituto di Supabase?
No. Vivono su livelli diversi — Supabase è il tuo backend (database, auth, storage, realtime), mentre Drizzle è solo un ORM che interroga un database. Non sostituisci l'uno con l'altro; semmai, Drizzle interroga il database Postgres che Supabase ospita.
Ho bisogno di Drizzle se uso già Supabase?
No — è completamente opzionale. supabase-js gestisce la maggior parte delle app perfettamente. Aggiungi Drizzle quando vuoi type safety a compile-time su query complesse o stai deployando su runtime edge dove la dimensione del bundle conta.
Posso usare Supabase e Drizzle insieme?
Sì, ed è la configurazione più comune in pratica. Mantieni supabase-js per auth, storage e realtime, poi punta Drizzle sulla stessa connessione Postgres di Supabase per le query dati. Coesistono felicemente nello stesso codebase.
Qual è la differenza tra supabase-js e Drizzle?
supabase-js è un client completo — accesso al database via PostgREST più auth, realtime e storage. Drizzle è un ORM Postgres diretto e type-safe senza auth o realtime; fa solo SQL in TypeScript. Uno è il client dell'intera piattaforma, l'altro è puramente un livello di query.
Drizzle funziona con Supabase Row Level Security (RLS)?
Sì. Mantieni RLS attivo e usa un client compatibile con RLS che avvolge le query in una transazione che imposta il contesto auth Postgres. Un client admin con chiave service-role bypassa RLS, quindi usalo solo lato server e non esporlo mai al browser.
Perché ho bisogno di prepare: false con Supabase e Drizzle?
Il pooler di connessioni in modalità transaction di Supabase non supporta le prepared statement, che il driver postgres-js di Drizzle usa per default. Impostare prepare: false evita gli errori risultanti. Omettilo e le tue query si romperanno in configurazioni pooled o serverless — spesso solo dopo il deploy.
Devo usare il pooler o la stringa di connessione diretta?
Usa il pooler (modalità transaction, porta 6543) per funzioni serverless e edge, e la connessione diretta (porta 5432) per server a lunga esecuzione. Il pooler è anche ciò che rende necessario prepare: false, quindi le due scelte vanno di pari passo.
Drizzle è gratuito? Supabase è gratuito?
Drizzle è completamente open-source — $0, incluso Drizzle Studio per lo sviluppo locale. Supabase ha un piano gratuito, poi Pro a $25/mese e Team a $599/mese (prezzi 2026). In breve: l'unico costo è Supabase, e Drizzle non aggiunge nulla a quel conto.
Drizzle vs Prisma per Supabase — quale ORM scegliere?
Entrambi funzionano con Supabase, quindi non puoi sbagliare di molto. Drizzle è più leggero (~7.4 kb) e edge-native; Prisma ha una developer experience più matura e un'adozione più ampia. Scegli Drizzle per edge e dimensione bundle, Prisma per ergonomia su server tradizionali.
Conclusione
Quindi, Supabase vs Drizzle? Non è mai stato davvero un confronto. Ecco cosa tenere a mente:
- Non sono competitor. Supabase è il tuo backend; Drizzle è un ORM type-safe opzionale che si posiziona sopra di esso.
- Usarli entrambi è la risposta più comune —
supabase-jsper auth/storage/realtime, Drizzle per le query dati pesanti. - Cura i dettagli di correttezza:
prepare: false, la stringa di connessione giusta e un client compatibile con RLS. Sono queste le cose che fanno inciampare i team in produzione. - Drizzle è gratuito, quindi aggiungerlo non costa nulla — l'unico conto è Supabase.
- Inizia semplice. Passa a Drizzle quando una query fa davvero male, non prima.

Ancora indeciso tra supabase-js, Drizzle o entrambi per il tuo stack? Richiedi una consulenza backend gratuita →