Bob le développeur
Estimer

Prisma vs TypeORM : retour d'expérience sur 8 projets NestJS

Bob Le Développeur

12/03/2026 · Mis à jour le 14/10/2026

On a utilisé TypeORM sur 7 projets NestJS et Prisma sur 1. Voici ce qu'on en retient : pas de la théorie, du vécu.

Le contexte

Quand on a commencé à construire des API NestJS en 2021, TypeORM était le choix par défaut. Intégration native avec NestJS, documentation correcte, communauté active. Puis Prisma est arrivé avec une approche radicalement différente : schema-first, type-safe par design, et une DX qui promettait de changer la donne.

On a basculé un projet sur Prisma pour voir. Voici ce qu'on a appris.

Définition des modèles : décorateurs vs schema

TypeORM définit les modèles avec des décorateurs TypeScript. C'est verbeux mais lisible :

@Entity()
export class Appointment extends BaseEntity {
  @PrimaryGeneratedColumn('uuid')
  id: string;

  @ManyToOne(() => Workspace, (ws) => ws.appointments)
  @JoinColumn()
  workspace: Workspace;

  @ManyToOne(() => Project, (p) => p.appointments)
  @JoinColumn()
  project: Project;
}

Prisma utilise un fichier .prisma dédié, plus concis :

model Relationship {
  id         String   @id @default(uuid())
  createdAt  DateTime @default(now())
  updatedAt  DateTime @updatedAt
  deletedAt  DateTime?
  sponsor    User?    @relation("Sponsor", fields: [sponsorId], references: [id])
  downline   User?    @relation("Downline", fields: [downlineId], references: [id])
  sponsorId  String?
  downlineId String?
  status     String   @default("PENDING")
}

Notre tip : le schema Prisma est plus rapide à lire et à modifier. Mais les décorateurs TypeORM permettent de garder la logique ORM avec le code TypeScript, pas de fichier séparé à synchroniser mentalement.

Typage : là où Prisma écrase

Le client Prisma génère des types à partir du schema. Quand on écrit prisma.relationship.findMany(), l'autocomplétion connaît exactement les champs, les relations, et les filtres possibles. C'est du type-safety de bout en bout, sans effort.

Avec TypeORM, le typage existe mais il est plus lâche. Depuis la version 0.3, les relations d'un find() s'écrivent sous forme d'objet et sont vérifiées à la compilation (l'ancienne syntaxe en tableau de chaînes, qui ne l'était pas, a été retirée en 1.0). En revanche, le type renvoyé ne dit pas quelles relations ont été chargées : une relation non demandée vaut undefined à l'exécution alors que son type promet un objet.

Notre tip : sur un projet avec beaucoup de relations complexes (self-referencing, many-to-many), le typage Prisma évite des bugs qu'on ne découvrirait qu'en prod avec TypeORM.

Soft deletes : avantage TypeORM

TypeORM gère les soft deletes nativement avec @DeleteDateColumn() :

export class BaseEntity {
  @CreateDateColumn()
  createdAt: Date;

  @UpdateDateColumn()
  updatedAt: Date;

  @DeleteDateColumn()
  deletedAt?: Date;
}

Un softDelete() remplit le champ, et tous les find() excluent automatiquement les entités supprimées. Transparent.

Prisma n'a pas de soft delete natif. On ajoute un champ deletedAt DateTime? et on doit filtrer manuellement partout avec where: { deletedAt: null }. Sur un projet avec 15+ entités, c'est une source d'erreurs.

Notre tip : si le soft delete est central dans votre logique (audit trail, RGPD, corbeille), TypeORM simplifie la vie. Avec Prisma, prévoyez une extension Prisma Client ($extends, composant query) pour automatiser le filtrage : le middleware $use a été retiré en version 6.14. Elle ne couvre pas les relations chargées avec include, qu'il faut encore filtrer à la main.

Migrations : deux philosophies

TypeORM peut auto-synchroniser le schéma en dev (synchronize: true). Pratique mais dangereux, on l'a désactivé en prod dès le premier jour. Les migrations (écrites à la main ou générées depuis le diff des entités avec migration:generate) fonctionnent, mais on a accumulé 86 fichiers de migration sur un projet. Le tooling est correct sans plus.

Prisma a un workflow migration plus propre : prisma migrate dev crée une migration à partir du diff du schema. C'est plus prévisible et le fichier SQL généré est lisible. Par contre, une migration de données demande une étape de plus : prisma migrate dev --create-only génère le fichier SQL sans l'appliquer, on y ajoute ses requêtes, puis on l'applique, le tout en SQL et sans code applicatif.

Notre tip : Prisma gagne sur les migrations de schéma. TypeORM gagne quand on a besoin de migrations de données complexes.

Relations self-referencing : Prisma gagne

Sur le projet MLM (réseau de parrainage), on avait une relation self-referencing : un utilisateur sponsorise d'autres utilisateurs, qui sponsorisent d'autres utilisateurs. Avec Prisma, c'est déclaratif et clair grâce aux relations nommées (@relation("Sponsor"), @relation("Downline")).

Avec TypeORM, les self-referencing many-to-many nécessitent plus de configuration et le eager loading devient vite un piège de performance si on ne fait pas attention.

Performance : pas de différence notable

Sur nos volumes (quelques milliers à quelques dizaines de milliers de lignes), on n'a pas mesuré de différence significative. Les deux génèrent du SQL propre. Les problèmes de performance viennent toujours du même endroit : des N+1 queries qu'on n'a pas anticipées.

Notre verdict

Critère TypeORM Prisma
DX / autocomplétion Correct Excellent
Soft deletes Natif Manuel
Migrations schema Correct Meilleur
Migrations data Flexible Limité
Self-referencing Verbeux Clair
Écosystème NestJS Module officiel (@nestjs/typeorm) Service à écrire (recette officielle)
Courbe d'apprentissage Progressive Rapide

Si on démarrait un nouveau projet NestJS aujourd'hui : Prisma pour les projets avec beaucoup de relations complexes et une équipe qui valorise la DX. TypeORM pour les projets qui ont besoin de soft deletes natifs, de migrations de données flexibles, ou qui préfèrent le module officiel @nestjs/typeorm à un service Prisma écrit à la main.

En pratique, les deux font le job. Le choix dépend plus de l'équipe que de la technologie.

Stack concernée : NestJS, PostgreSQL, TypeORM 0.2-0.3, Prisma 5

Ce contenu vous a servi ? Ajoutez Bob le développeur à vos sources préférées sur Google.

Renfort

Besoin de renfort dans votre équipe ?

Des développeurs React, Next.js et Node.js seniors, intégrés à vos sprints et à vos revues de code.

  • Démarrage en quelques jours
  • Engagement au mois

30 min, gratuit, sans engagement.

La newsletter qu’on n’ignore pas

Abonnez-vous à notre newsletter pour recevoir nos derniers articles, retours d’expérience et conseils tech directement dans votre boîte mail.

Désinscription en un clic. Vos données restent privées.