TrueSpec

TypeORM with NestJS

Entity setup, repositories, migrations, relations, and query builder

What You’ll Build

After following this guide, you will have a working implementation of typeorm with nestjs in your project. Set up TypeORM with NestJS for a fully typed, enterprise-grade data layer. NestJS’s module system integrates cleanly with TypeORM’s repository pattern. Covers entity definitions, relations, migration generation, and the query builder for complex queries.

Use Cases & Problems Solved

  • Set up a production-ready database layer with type-safe queries
  • Manage schema changes through migrations without data loss
  • Avoid raw SQL injection risks and inconsistent data access patterns

Prerequisites

  • NestJS project
  • PostgreSQL database
  • TypeScript

Step-by-Step Implementation

Install TypeORM integration

The following snippet shows how to install typeorm integration. Copy this into your project and adjust the values for your environment.

npm install @nestjs/typeorm typeorm pg

Configure in AppModule

The following snippet shows how to configure in appmodule. Copy this into your project and adjust the values for your environment.

// app.module.ts
import { TypeOrmModule } from '@nestjs/typeorm';

@Module({
  imports: [
    TypeOrmModule.forRoot({
      type: 'postgres',
      url: process.env.DATABASE_URL,
      entities: [__dirname + '/**/*.entity{.ts,.js}'],
      synchronize: process.env.NODE_ENV !== 'production', // auto-sync in dev only!
    }),
    UsersModule,
  ],
})
export class AppModule {}

Define entity and service

The following snippet shows how to define entity and service. Copy this into your project and adjust the values for your environment.

// user.entity.ts
import { Entity, PrimaryGeneratedColumn, Column, OneToMany } from 'typeorm';

@Entity()
export class User {
  @PrimaryGeneratedColumn()
  id: number;

  @Column({ unique: true })
  email: string;

  @Column()
  name: string;

  @OneToMany(() => Post, post => post.author)
  posts: Post[];
}

// users.service.ts
@Injectable()
export class UsersService {
  constructor(@InjectRepository(User) private usersRepo: Repository<User>) {}

  findAll() { return this.usersRepo.find({ relations: ['posts'] }); }
  findOne(id: number) { return this.usersRepo.findOneBy({ id }); }
  create(dto: CreateUserDto) { return this.usersRepo.save(dto); }
}

⚠️ Don’t Do This

❌ Using synchronize: true in production

TypeOrmModule.forRoot({
  synchronize: true, // DANGEROUS in production!
  // Auto-alters tables — can DROP COLUMNS with data!
})

✅ Use migrations in production, synchronize only in development

TypeOrmModule.forRoot({
  synchronize: process.env.NODE_ENV !== 'production',
  migrationsRun: true, // Run pending migrations on startup
  migrations: [__dirname + '/migrations/*{.ts,.js}'],
})
// Generate migrations: npx typeorm migration:generate -n AddUserPhone

Testing

Verify your implementation with these tests:

// __tests__/typeorm-with-nestjs.test.ts
import { describe, it, expect } from 'vitest';

describe('TypeORM with NestJS', () => {
  it('should initialize without errors', () => {
    // Test that the setup completes successfully
    expect(() => setup()).not.toThrow();
  });

  it('should handle the primary use case', async () => {
    const result = await execute();
    expect(result).toBeDefined();
    expect(result.success).toBe(true);
  });

  it('should handle edge cases', async () => {
    // Test with empty/null input
    const result = await execute(null);
    expect(result.error).toBeDefined();
  });
});

Verification

npm run start:dev
# Check NestJS logs for 'TypeORM connected' message
# Test with curl:
curl http://localhost:3000/users
# Should return [] initially, then data after POST

Related Specs

Beginner

Prisma + PostgreSQL Full Setup

Schema design, migrations, seeding, CRUD operations, and relations

Database & ORM
Intermediate

Supabase Row-Level Security

RLS policies for user-scoped data, admin bypass, and testing

Database & ORM
Advanced

Safe Database Migrations

Zero-downtime migration patterns, rollback strategies, and data backfills

Database & ORM