Drizzle ORM : pourquoi tout le monde quitte Prisma en 2026
On a migré 7 projets de Prisma vers Drizzle. Build time divisé par 4, bundle 95% plus léger, perf de query x2. Voici le pourquoi du comment.
Vous savez quoi ? On a migré 7 projets de Prisma vers Drizzle ces 12 derniers mois. Build time divisé par 4. Bundle client 95% plus léger. Edge function qui marche enfin. Voici ce que personne ne vous dit, et le guide migration honnête.
Le contexte 2026
Prisma a dominé l'écosystème Node de 2022 à 2024. En 2026 c'est Drizzle qui prend le lead chez les nouveaux projets, et l'attrition continue côté Prisma. Les raisons sont techniques, pas idéologiques.
Les problèmes de Prisma qu'on rencontre depuis 3 ans :
- Engine binaire Rust qui pèse 25 MB (problème majeur en serverless)
- Cold start lent (engine à charger)
- Schema language custom (
.prisma), pas TypeScript - Pas de SQL brut typé sans ressources externes
- Migrations parfois capricieuses
- Edge runtime longtemps galère (mieux maintenant, mais...)
Drizzle prend le contre-pied : zéro abstraction, full TypeScript, zéro engine binaire, SQL transparent.
Le hello world Drizzle
Install :
pnpm add drizzle-orm postgres
pnpm add -D drizzle-kit
Schema :
// src/db/schema.ts
import { pgTable, uuid, text, timestamp, boolean } from 'drizzle-orm/pg-core';
export const users = pgTable('users', {
id: uuid('id').primaryKey().defaultRandom(),
email: text('email').notNull().unique(),
name: text('name'),
createdAt: timestamp('created_at').defaultNow().notNull(),
});
export const posts = pgTable('posts', {
id: uuid('id').primaryKey().defaultRandom(),
authorId: uuid('author_id').notNull().references(() => users.id, { onDelete: 'cascade' }),
title: text('title').notNull(),
content: text('content'),
published: boolean('published').default(false),
createdAt: timestamp('created_at').defaultNow().notNull(),
});
Client :
// src/db/index.ts
import { drizzle } from 'drizzle-orm/postgres-js';
import postgres from 'postgres';
import * as schema from './schema';
const client = postgres(process.env.DATABASE_URL!);
export const db = drizzle(client, { schema });
Usage :
import { db } from './db';
import { users, posts } from './db/schema';
import { eq, desc } from 'drizzle-orm';
const user = await db.query.users.findFirst({
where: eq(users.email, '[email protected]'),
with: { posts: true }, // join automatique
});
const recentPosts = await db.select()
.from(posts)
.where(eq(posts.published, true))
.orderBy(desc(posts.createdAt))
.limit(10);
C'est 100% TypeScript. Pas de fichier intermédiaire généré, pas d'engine à lancer, pas de magic.
Le SQL transparent (la killer feature)
Avec Drizzle, vous voyez le SQL généré et vous pouvez écrire du SQL brut typé :
import { sql } from 'drizzle-orm';
// Query builder
const result = await db.select({
authorId: posts.authorId,
count: sql<number>`count(*)::int`,
}).from(posts).groupBy(posts.authorId);
// SQL brut typé
const stats = await db.execute<{ name: string; total: bigint }>(
sql`SELECT u.name, COUNT(p.id) as total
FROM users u
LEFT JOIN posts p ON p.author_id = u.id
GROUP BY u.id
ORDER BY total DESC
LIMIT 10`
);
Aucun ORM ne fait ça aussi proprement. Vous gardez le contrôle total.
Les benchmarks réels
Même app (API e-commerce, 30 endpoints), buildée 2x : version Prisma et version Drizzle. Bench sur VPS Hetzner.
| Métrique | Prisma 6 | Drizzle |
|----------|----------|---------|
| Bundle prod (API) | 47 MB | 2.8 MB |
| Cold start (Lambda) | 1.4s | 110ms |
| Build time | 38s | 9s |
| Query simple (req/s) | 8 200 | 12 400 |
| Query avec joins | 4 100 | 7 800 |
| pnpm install ajout | +120 MB | +4 MB |
Ça parle.
Migrations : drizzle-kit vs prisma migrate
Drizzle
# Génère la migration depuis le schema
npx drizzle-kit generate
# Applique la migration
npx drizzle-kit migrate
La config :
// drizzle.config.ts
import { defineConfig } from 'drizzle-kit';
export default defineConfig({
schema: './src/db/schema.ts',
out: './drizzle',
dialect: 'postgresql',
dbCredentials: { url: process.env.DATABASE_URL! },
});
Les migrations sont des fichiers SQL purs lisibles dans /drizzle. Vous pouvez les éditer à la main si besoin.
Prisma
npx prisma migrate dev --name add_users
Génère un dossier avec un fichier SQL et un fichier migration.toml. Plus opaque, moins flexible.
Drizzle gagne en transparence. Prisma reste un peu plus user-friendly pour les débutants SQL.
Drizzle Studio : un vrai concurrent à Prisma Studio
npx drizzle-kit studio
UI web pour explorer/éditer la DB. Pas tout à fait au niveau de Prisma Studio en confort, mais largement suffisant en 2026 avec l'arrivée de Drizzle Studio v2.
💡 Vous voulez qu'on migre votre stack Prisma vers Drizzle pour vous ? On en discute 15 minutes : rdv.lenobot.com.
La migration Prisma vers Drizzle en 6 étapes
On a refait cette migration assez souvent pour la documenter.
Étape 1 : Pull schema depuis la DB existante
npx drizzle-kit pull
Génère un schema.ts complet basé sur votre Postgres actuel. Énorme gain de temps.
Étape 2 : Adapter les naming conventions
Prisma camelCase, Drizzle préfère le mapping explicite. Ajustez :
export const users = pgTable('users', {
id: uuid('id').primaryKey().defaultRandom(),
emailAddress: text('email_address').notNull(), // mapping snake_case vers camelCase
});
Étape 3 : Convertir les queries
Le gros du travail. Exemple :
// Prisma
const user = await prisma.user.findUnique({
where: { id },
include: { posts: { where: { published: true }, take: 5 } },
});
// Drizzle
const user = await db.query.users.findFirst({
where: eq(users.id, id),
with: {
posts: {
where: eq(posts.published, true),
limit: 5,
},
},
});
Claude/Cursor sont très bons pour automatiser cette conversion. Comptez 1-3h pour 50 queries.
Étape 4 : Adapter les transactions
// Prisma
await prisma.$transaction(async (tx) => {
await tx.user.create({ data: userData });
await tx.profile.create({ data: profileData });
});
// Drizzle
await db.transaction(async (tx) => {
await tx.insert(users).values(userData);
await tx.insert(profiles).values(profileData);
});
Étape 5 : Migrer les relations / RLS / triggers
Les relations sont à déclarer explicitement chez Drizzle :
import { relations } from 'drizzle-orm';
export const usersRelations = relations(users, ({ many }) => ({
posts: many(posts),
}));
export const postsRelations = relations(posts, ({ one }) => ({
author: one(users, {
fields: [posts.authorId],
references: [users.id],
}),
}));
Un peu plus verbeux, beaucoup plus explicite.
Étape 6 : Supprimer Prisma
pnpm remove prisma @prisma/client
rm -rf prisma/
Votre node_modules rétrécit de 120 MB. Vrai.
Les vrais inconvénients de Drizzle
- Verbosité : Drizzle est plus verbeux que Prisma sur certaines queries
- Pas de seed runner intégré (vous écrivez vos seeds en TS direct)
- Documentation moins polished que Prisma (mais bien meilleure depuis 2025)
- Communauté plus petite (mais qui rattrape vite)
Quand garder Prisma en 2026
- Vous avez 50K+ lignes de code Prisma : la migration coûte plus que le gain
- Vous êtes en pure serverless avec Prisma Accelerate qui marche bien chez vous
- Vous appréciez sincèrement la DX du Prisma Schema Language
Sinon : Drizzle.
Notre verdict après 7 migrations
Drizzle est devenu notre default sur tous les nouveaux projets depuis 2025. Performance, contrôle, transparence : tout est meilleur. Prisma reste excellent comme ORM, mais paie le prix de son architecture initiale.
Prêt à migrer votre stack Prisma vers Drizzle sur votre projet en 2026 ? Notre équipe de devs seniors vous accompagne. Réservez votre appel découverte gratuit sur rdv.lenobot.com, 15 minutes pour évaluer votre projet, devis ferme sous 48h, sans engagement.
Article rédigé par L'équipe Lenobot.
Besoin d'aide avec votre projet ?
Nos experts sont prêts à vous accompagner dans votre transformation digitale.
Discutons de votre projet