ORM for TypeScript: Comparison and usage examples
In modern TypeScript development, choosing the right ORM (Object-Relational Mapping) is a fundamental decision that affects performance, code readability, and development speed. In this article, we will compare in detail the three most popular ORMs for TypeScript: Prisma, TypeORM, and MikroORM. You will learn their strengths and weaknesses, see code examples, and get practical recommendations for your project.
1. Prisma — the modern standard
Prisma is a next-generation ORM that uses its own declarative schema language. It automatically generates a type-safe client based on your database schema. Prisma supports PostgreSQL, MySQL, SQLite, SQL Server, and MongoDB.
Advantages:
- Powerful type system — all queries are checked at compile time
- Built-in migrations and the Prisma Studio visual editor
- Excellent documentation and an active community
- Autocomplete in the IDE
Disadvantages:
- An additional client generation step
- Less flexibility for complex SQL queries
- Relatively large package size
Code example:
// schema.prismamodel User { id Int @id @default(autoincrement()) email String @unique name String? posts Post[]}
model Post { id Int @id @default(autoincrement()) title String content String? authorId Int author User @relation(fields: [authorId], references: [id])}// app.tsimport { PrismaClient } from '@prisma/client';
const prisma = new PrismaClient();
async function main() { // Creating a user with a post const user = await prisma.user.create({ data: { email: 'alice@example.com', name: 'Alice', posts: { create: { title: 'Hello World' } } }, include: { posts: true } });
// Searching with filtering const users = await prisma.user.findMany({ where: { email: { contains: 'alice' } }, orderBy: { name: 'asc' } });
console.log(users);}
main();2. TypeORM — a proven veteran
TypeORM is one of the oldest ORMs for TypeScript, inspired by Hibernate and Entity Framework. It uses decorators to define entities and supports Active Record and Data Mapper patterns. It works with most relational databases.
Advantages:
- Flexible decorator system
- Support for migrations and schema synchronization
- Large number of integrations and extensions
- A mature and time-tested project
Disadvantages:
- Less strict typing compared to Prisma
- Complex configuration for beginners
- Slow development recently
Code example:
// entity/User.tsimport { Entity, PrimaryGeneratedColumn, Column, OneToMany } from 'typeorm';import { Post } from './Post';
@Entity()export class User { @PrimaryGeneratedColumn() id: number;
@Column({ unique: true }) email: string;
@Column({ nullable: true }) name: string;
@OneToMany(() => Post, (post) => post.author) posts: Post[];}// app.tsimport { createConnection } from 'typeorm';import { User } from './entity/User';
async function main() { const connection = await createConnection(); const userRepo = connection.getRepository(User);
// Creating const user = userRepo.create({ email: 'bob@example.com', name: 'Bob' }); await userRepo.save(user);
// Searching const users = await userRepo.find({ where: { name: Like('%Bob%') }, relations: ['posts'] });
console.log(users);}
main();