ORM for TypeScript: comparison and examples
In modern web development with TypeScript, choosing the right ORM (Object-Relational Mapping) is one of the key decisions that affects the architecture, performance, and maintainability of a project. An ORM allows you to work with a database through programming language objects, abstracting SQL queries. In this article, we will look at three of the most popular ORMs for TypeScript: TypeORM, Prisma and MikroORM. You will learn their strengths and weaknesses, and also see code examples for each of them.
1. TypeORM
TypeORM is one of the oldest and most mature ORMs for TypeScript and JavaScript. It supports Active Record and Data Mapper patterns, as well as many databases: PostgreSQL, MySQL, SQLite, MongoDB and others.
Features of TypeORM:
- Support for decorators for defining entities
- Flexible relationships: OneToOne, OneToMany, ManyToMany
- Migrations and schema synchronization
- Support for subscriptions and lifecycle events
- Query Builder for complex queries
Code example with TypeORM:
import { Entity, PrimaryGeneratedColumn, Column, BaseEntity, createConnection } from "typeorm";
@Entity()export class User extends BaseEntity { @PrimaryGeneratedColumn() id: number;
@Column() name: string;
@Column() email: string;}
async function main() { await createConnection({ type: "postgres", host: "localhost", port: 5432, username: "test", password: "test", database: "test", entities: [User], synchronize: true, });
const user = new User(); user.name = "Ivan"; user.email = "ivan@example.com"; await user.save();
const users = await User.find(); console.log(users);}Pros: large community, many tutorials, MongoDB support. Cons: complex configuration, problems with lazy loading, sometimes non-intuitive API.
2. Prisma
Prisma is a modern ORM that rethinks the approach to working with a database. Instead of a traditional ORM, it offers three components: Prisma Client (an automatically generated type-safe client), Prisma Migrate (a migration system) and Prisma Studio (a graphical interface).
Features of Prisma:
- Declarative data schema (schema.prisma)
- Full typing based on the schema — no manual types
- Automatic client generation
- Support for transactions and pagination
- Integration with GraphQL (Nexus, TypeGraphQL)
Code example with Prisma:
// schema.prismamodel User { id Int @id @default(autoincrement()) name String email String @unique posts Post[]}
model Post { id Int @id @default(autoincrement()) title String content String? authorId Int author User @relation(fields: [authorId], references: [id])}
// main.tsimport { PrismaClient } from '@prisma/client';
const prisma = new PrismaClient();
async function main() { const user = await prisma.user.create({ data: { name: 'Maria', email: 'maria@example.com', posts: { create: { title: 'My first post' } } }, include: { posts: true } });
const users = await prisma.user.findMany({ include: { posts: true } }); console.log(users);}
main() .catch(e => console.error(e)) .finally(() => prisma.$disconnect());Pros: best-in-class typing, simple syntax, excellent documentation. Cons: schema dependency, complexity with custom queries, higher memory consumption.
3. MikroORM
MikroORM is a micro-ORM inspired by Doctrine
Also in library
Redis client for Rust: overview of the redis-rs library
UUID for JavaScript (Node.js): Complete Guide with Examples
gRPC for Swift (iOS/macOS): Libraries, Setup, and Examples
JWT tokens in C# (.NET): working with System.IdentityModel.Tokens.Jwt