What it is
TypeORM is a decorator-based ORM for TypeScript supporting both Active Record and Data Mapper patterns, with migrations, relations and a query builder.
Entities are classes with column decorators. Repositories provide CRUD; the query builder covers anything more complex.
Installation
npm install typeorm reflect-metadata pgGetting started
The smallest useful thing you can do with it, and what each part means.
typescript
@Entity()
export class Book {
@PrimaryGeneratedColumn()
id: number;
@Column({ length: 200 })
title: string;
@ManyToOne(() => Author, (author) => author.books)
author: Author;
@CreateDateColumn()
createdAt: Date;
}
const repo = dataSource.getRepository(Book);
const books = await repo.find({
where: { title: ILike('%dune%') },
relations: { author: true }, // otherwise author is undefined
order: { createdAt: 'DESC' },
take: 10,
});Advanced usage
Where the library earns its place over a simpler alternative.
typescript
const rows = await repo
.createQueryBuilder('book')
.innerJoinAndSelect('book.author', 'author')
.where('book.year >= :year', { year: 1990 }) // always parameterise
.andWhere('author.country = :country', { country: 'US' })
.orderBy('book.year', 'DESC')
.limit(10)
.getMany();
await dataSource.transaction(async (manager) => {
await manager.decrement(Stock, { sku }, 'quantity', qty);
await manager.save(Order, { sku, qty });
});Errors and fixes
The failures you are most likely to hit, and what actually resolves them.
- No metadata for Book was found
- The entity is not registered in DataSource entities, or reflect-metadata was not imported at the entry point.
- Relation is undefined
- It was not eagerly loaded. Add it to relations or join it in the query builder.
Best practices
- Always specify relations explicitly; unloaded ones are silently undefined.
- Use parameterised where clauses, never template interpolation.
- Disable synchronize in production — it can drop columns. Use migrations.
- Consider Prisma or Drizzle for new projects; their type inference is considerably stronger.
Background
Why it exists, and what it was reacting to.
TypeORM was the first widely adopted TypeScript ORM and remains the default in many NestJS projects, though its type inference is weaker than newer alternatives such as Prisma and Drizzle.
