{"id":13818188,"url":"https://github.com/mikro-orm/nestjs","last_synced_at":"2025-10-21T06:45:46.443Z","repository":{"id":38846022,"uuid":"281663065","full_name":"mikro-orm/nestjs","owner":"mikro-orm","description":"NestJS MikroORM integration","archived":false,"fork":false,"pushed_at":"2025-04-21T19:01:17.000Z","size":1382,"stargazers_count":238,"open_issues_count":6,"forks_count":31,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-04-21T20:21:59.771Z","etag":null,"topics":["mikro-orm","nest","nestjs","typescript"],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mikro-orm.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null},"funding":{"github":["B4nan"],"custom":"https://paypal.me/mikroorm"}},"created_at":"2020-07-22T11:49:30.000Z","updated_at":"2025-04-21T19:01:22.000Z","dependencies_parsed_at":"2023-12-25T21:21:57.260Z","dependency_job_id":"f4fb243d-7433-4a2a-9065-8d8786d03581","html_url":"https://github.com/mikro-orm/nestjs","commit_stats":{"total_commits":226,"total_committers":21,"mean_commits":"10.761904761904763","dds":0.6238938053097345,"last_synced_commit":"87fd6b86b9222dca8e82d15c3916f6790c9bcc75"},"previous_names":[],"tags_count":16,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mikro-orm%2Fnestjs","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mikro-orm%2Fnestjs/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mikro-orm%2Fnestjs/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mikro-orm%2Fnestjs/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mikro-orm","download_url":"https://codeload.github.com/mikro-orm/nestjs/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254249206,"owners_count":22039029,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["mikro-orm","nest","nestjs","typescript"],"created_at":"2024-08-04T07:00:35.355Z","updated_at":"2025-10-21T06:45:46.423Z","avatar_url":"https://github.com/mikro-orm.png","language":"TypeScript","readme":"\u003cp align=\"center\" style=\"vertical-align:middle\"\u003e\n  \u003ca href=\"https://nestjs.com/\" target=\"blank\"\u003e\u003cimg src=\"https://nestjs.com/img/logo_text.svg\" width=\"200\" alt=\"Nest Logo\" /\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"https://mikro-orm.io/\" target=\"blank\"\u003e\u003cimg src=\"https://raw.githubusercontent.com/mikro-orm/mikro-orm/master/docs/static/img/logo-readme.svg?sanitize=true\" width=\"200\" alt=\"MikroORM\"\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n\u003e Based on [dario1985/nestjs-mikro-orm](https://github.com/dario1985/nestjs-mikro-orm).\n\n[![NPM version](https://img.shields.io/npm/v/@mikro-orm/nestjs.svg)](https://www.npmjs.com/package/@mikro-orm/nestjs)\n[![Chat on slack](https://img.shields.io/badge/chat-on%20slack-blue.svg)](https://join.slack.com/t/mikroorm/shared_invite/enQtNTM1ODYzMzM4MDk3LWM4ZDExMjU5ZDhmNjA2MmM3MWMwZmExNjhhNDdiYTMwNWM0MGY5ZTE3ZjkyZTMzOWExNDgyYmMzNDE1NDI5NjA)\n[![Downloads](https://img.shields.io/npm/dm/@mikro-orm/nestjs.svg)](https://www.npmjs.com/package/@mikro-orm/nestjs)\n[![Build Status](https://github.com/mikro-orm/nestjs/workflows/tests/badge.svg?branch=master)](https://github.com/mikro-orm/nestjs/actions?workflow=tests)\n\n## Description\n\nThe [MikroORM](https://github.com/mikro-orm/mikro-orm) module for [NestJS](https://github.com/nestjs/nest).\n\n## 🚀 Quick Start\n\nFirst install the module via `yarn` or `npm` and do not forget to install the database driver as well:\n\n```bash\n$ yarn add @mikro-orm/core @mikro-orm/nestjs @mikro-orm/mongodb     # for mongo\n$ yarn add @mikro-orm/core @mikro-orm/nestjs @mikro-orm/mysql       # for mysql/mariadb\n$ yarn add @mikro-orm/core @mikro-orm/nestjs @mikro-orm/mariadb     # for mysql/mariadb\n$ yarn add @mikro-orm/core @mikro-orm/nestjs @mikro-orm/postgresql  # for postgresql\n$ yarn add @mikro-orm/core @mikro-orm/nestjs @mikro-orm/sqlite      # for sqlite\n```\n\nor\n\n```bash\n$ npm i -s @mikro-orm/core @mikro-orm/nestjs @mikro-orm/mongodb     # for mongo\n$ npm i -s @mikro-orm/core @mikro-orm/nestjs @mikro-orm/mysql       # for mysql/mariadb\n$ npm i -s @mikro-orm/core @mikro-orm/nestjs @mikro-orm/mariadb     # for mysql/mariadb\n$ npm i -s @mikro-orm/core @mikro-orm/nestjs @mikro-orm/postgresql  # for postgresql\n$ npm i -s @mikro-orm/core @mikro-orm/nestjs @mikro-orm/sqlite      # for sqlite\n```\n\nOnce the installation process is completed, we can import the `MikroOrmModule` into the root `AppModule`.\n\n```typescript\n@Module({\n  imports: [\n    MikroOrmModule.forRoot({\n      entities: ['../dist/entities'],\n      entitiesTs: ['../src/entities'],\n      dbName: 'my-db-name.sqlite3',\n      type: 'sqlite',\n      baseDir: __dirname,\n    }),\n  ],\n  controllers: [AppController],\n  providers: [AppService],\n})\nexport class AppModule {}\n```\n\nThe `forRoot()` method accepts the same configuration object as `init()` from the MikroORM package. \nYou can also omit the parameter to use the CLI config.\n\nAfterward, the `EntityManager` will be available to inject across entire project (without importing any module elsewhere).\n\n```ts\n@Injectable()\nexport class MyService {\n\n  constructor(private readonly orm: MikroORM,\n              private readonly em: EntityManager) { }\n\n}\n```\n\nTo define which repositories shall be registered in the current scope you can use the `forFeature()` method. For example, in this way:\n\n\u003e You should **not** register your base entities via `forFeature()`, as there are no\n\u003e repositories for those. On the other hand, base entities need to be part of the list\n\u003e in `forRoot()` (or in the ORM config in general).\n\n```typescript\n// photo.module.ts\n\n@Module({\n  imports: [MikroOrmModule.forFeature([Photo])],\n  providers: [PhotoService],\n  controllers: [PhotoController],\n})\nexport class PhotoModule {}\n```\n\nand import it into the root `AppModule`:\n\n```typescript\n// app.module.ts\n@Module({\n  imports: [MikroOrmModule.forRoot(...), PhotoModule],\n})\nexport class AppModule {}\n```\n\nIn this way we can inject the `PhotoRepository` to the `PhotoService` using the `@InjectRepository()` decorator:\n\n```typescript\n@Injectable()\nexport class PhotoService {\n  constructor(\n    @InjectRepository(Photo)\n    private readonly photoRepository: EntityRepository\u003cPhoto\u003e\n  ) {}\n\n  // ...\n\n}\n```\n\n## Driver-specific imports\n\nWhen you try to inject the `EntityManager` or `MikroORM` symbols exported from the driver package, Nest.js needs to be aware of those typed. In other words, those driver specific exports need to be specifically registered in the DI container. This module uses automated discovery of the driver type in order to do that, but it fails to work when you use `useFactory` which requires some dependencies.\n\nInstead of relying on this discovery, you can provide the driver type explicitly:\n\n```typescript\n@Module({\n  imports: [\n    MikroOrmModule.forRootAsync({\n      useFactory: (configService: ConfigService) =\u003e configService.getOrThrow(ConfigKey.ORM),\n      inject: [ConfigService],\n      driver: PostgreSqlDriver,\n    }),\n  ],\n  controllers: [AppController],\n  providers: [AppService],\n})\nexport class AppModule {}\n```\n\n## Load entities automatically\n\nManually adding entities to the entities array of the connection options can be \ntedious. In addition, referencing entities from the root module breaks application \ndomain boundaries and causes leaking implementation details to other parts of the \napplication. To solve this issue, static glob paths can be used.\n\nNote, however, that glob paths are not supported by webpack, so if you are building \nyour application within a monorepo, you won't be able to use them. To address this \nissue, an alternative solution is provided. To automatically load entities, set the \n`autoLoadEntities` property of the configuration object (passed into the `forRoot()` \nmethod) to `true`, as shown below: \n\n```ts\n@Module({\n  imports: [\n    MikroOrmModule.forRoot({\n      ...\n      autoLoadEntities: true,\n    }),\n  ],\n})\nexport class AppModule {}\n```\n\nWith that option specified, every entity registered through the `forFeature()` \nmethod will be automatically added to the entities array of the configuration \nobject.\n\n\u003e Note that entities that aren't registered through the `forFeature()` method, but \n\u003e are only referenced from the entity (via a relationship), won't be included by \n\u003e way of the `autoLoadEntities` setting.\n\n\u003e Using `autoLoadEntities` also has no effect on the MikroORM CLI - for that we \n\u003e still need CLI config with the full list of entities. On the other hand, we can\n\u003e use globs there, as the CLI won't go thru webpack.\n\n## Request scoped handlers in queues\n\nAs mentioned in the docs, we need a clean state for each request. That is handled\nautomatically thanks to the `RequestContext` helper registered via middleware. \n\nBut middlewares are executed only for regular HTTP request handles, what if we need\na request scoped method outside of that? One example of that is queue handlers or \nscheduled tasks. \n\nWe can use the `@CreateRequestContext()` decorator. It requires you to first inject the\n`MikroORM` instance to current context, it will be then used to create the context \nfor you. Under the hood, the decorator will register new request context for your \nmethod and execute it inside the context. \n\n```ts\n@Injectable()\nexport class MyService {\n\n  constructor(private readonly orm: MikroORM) { }\n\n  @CreateRequestContext()\n  async doSomething() {\n    // this will be executed in a separate context\n  }\n\n}\n```\n\n## Serialization caveat\n\n[NestJS built-in serialization](https://docs.nestjs.com/techniques/serialization) relies on [class-transformer](https://github.com/typestack/class-transformer). Since MikroORM wraps every single entity relation in a `Reference` or a `Collection` instance (for type-safety), this will make the built-in `ClassSerializerInterceptor` blind to any wrapped relations. In other words, if you return MikroORM entities from your HTTP or WebSocket handlers, all of their relations will NOT be serialized.\n\nLuckily, MikroORM provides a [serialization API](https://mikro-orm.io/docs/serializing) which can be used in lieu of `ClassSerializerInterceptor`.\n\n```typescript\n@Entity()\nexport class Book {\n\n  @Property({ hidden: true })   // --\u003e Equivalent of class-transformer's `@Exclude`\n  hiddenField: number = Date.now();\n  \n  @Property({ persist: false }) // --\u003e Will only exist in memory (and will be serialized). Similar to class-transformer's `@Expose()`\n  count?: number;\n  \n  @ManyToOne({ serializer: value =\u003e value.name, serializedName: 'authorName' })   // Equivalent of class-transformer's `@Transform()`\n  author: Author;\n\n}\n\n```\n\n## Using `AsyncLocalStorage` for request context\n\n\u003e Since v5 AsyncLocalStorage is used inside RequestContext helper so this section is no longer valid.\n\nBy default, the `domain` api is used in the `RequestContext` helper. Since `@mikro-orm/core@4.0.3`,\nyou can use the new `AsyncLocalStorage` too, if you are on up to date node version:\n\n```typescript\n// create new (global) storage instance\nconst storage = new AsyncLocalStorage\u003cEntityManager\u003e();\n\n@Module({\n  imports: [\n    MikroOrmModule.forRoot({\n      // ...\n      registerRequestContext: false, // disable automatatic middleware\n      context: () =\u003e storage.getStore(), // use our AsyncLocalStorage instance\n    }),\n  ],\n  controllers: [AppController],\n  providers: [AppService],\n})\nexport class AppModule {}\n\n// register the request context middleware\nconst app = await NestFactory.create(AppModule, { ... });\n\napp.use((req, res, next) =\u003e {\n  storage.run(orm.em.fork(true, true), next);\n});\n```\n\n## Using NestJS `Injection Scopes` for request context\n\nSince `@nestjs/common@6`, you can use the new `Injection Scopes` (https://docs.nestjs.com/fundamentals/injection-scopes) too:\n\n```typescript\nimport { Scope } from '@nestjs/common';\n\n@Module({\n  imports: [\n    MikroOrmModule.forRoot({\n      // ...\n      registerRequestContext: false, // disable automatatic middleware\n      scope: Scope.REQUEST\n    }),\n  ],\n  controllers: [AppController],\n  providers: [AppService]\n})\nexport class AppModule {}\n```\n\nOr, if you're using the Async provider:\n```typescript\nimport { Scope } from '@nestjs/common';\nimport { PostgreSqlDriver } from '@mikro-orm/postgresql';\n\n@Module({\n  imports: [\n    MikroOrmModule.forRootAsync({\n      // ...\n      useFactory: () =\u003e ({\n        // ...\n        registerRequestContext: false, // disable automatatic middleware\n      }),\n      scope: Scope.REQUEST\n    })\n  ],\n  controllers: [AppController],\n  providers: [AppService]\n})\nexport class AppModule {}\n```\n\n\u003e Please note that this might have some impact on performance,\n\u003e see: https://docs.nestjs.com/fundamentals/injection-scopes#performance\n\n## Using custom repositories\n\nWhen using custom repositories, we can get around the need for `@InjectRepository()`\ndecorator by naming our repositories the same way as `getRepositoryToken()` method do:\n\n```ts\nexport const getRepositoryToken = \u003cT\u003e (entity: EntityName\u003cT\u003e) =\u003e `${Utils.className(entity)}Repository`;\n```\n\nIn other words, as long as we name the repository same was as the entity is called, \nappending `Repository` suffix, the repository will be registered automatically in \nthe Nest.js DI container.\n\n`**./author.entity.ts**`\n\n```ts\n@Entity({ customRepository: () =\u003e AuthorRepository })\nexport class Author {\n\n  // to allow inference in `em.getRepository()`\n  [EntityRepositoryType]?: AuthorRepository;\n\n}\n```\n\n`**./author.repository.ts**`\n\n```ts\nexport class AuthorRepository extends EntityRepository\u003cAuthor\u003e {\n\n  // your custom methods...\n\n}\n```\n\nAs the custom repository name is the same as what `getRepositoryToken()` would\nreturn, we do not need the `@InjectRepository()` decorator anymore:\n\n```ts\n@Injectable()\nexport class MyService {\n\n  constructor(private readonly repo: AuthorRepository) { }\n\n}\n```\n\n## App shutdown and cleanup\n\nBy default, NestJS does not listen for system process termination signals (for example SIGTERM). Because of this, the MikroORM shutdown logic will never executed if the process is terminated, which could lead to database connections remaining open and consuming resources. To enable this, the `enableShutdownHooks` function needs to be called when starting up the application.\n\n```ts\nasync function bootstrap() {\n  const app = await NestFactory.create(AppModule);\n\n  // Starts listening for shutdown hooks\n  app.enableShutdownHooks();\n\n  await app.listen(3000);\n}\n```\n\nMore information about [enableShutdownHooks](https://docs.nestjs.com/fundamentals/lifecycle-events#application-shutdown)\n\n## Multiple Database Connections\n\nYou can define multiple database connections by registering multiple `MikroOrmModule`'s, each with a unique `contextName`. You will need to disable the automatic request context middleware by setting `registerRequestContext` to `false`, as it wouldn't work with this approach - note that this needs to be part of all your `MikroOrmModule`s with non-default `contextName`. To have the same automatic request context behaviour, you must register `MikroOrmModule` with `forMiddleware()` instead:\n\n```typescript\n@Module({\n  imports: [\n    MikroOrmModule.forRoot({\n      contextName: 'db1',\n      registerRequestContext: false, // disable automatatic middleware\n      ...\n    }),\n    MikroOrmModule.forRoot({\n      contextName: 'db2',\n      registerRequestContext: false, // disable automatatic middleware\n      ...\n    }),\n    MikroOrmModule.forMiddleware()\n  ],\n  controllers: [AppController],\n  providers: [AppService],\n})\nexport class AppModule {}\n```\n\nSince MikroORM v6.4, you can also define [multiple configurations](https://mikro-orm.io/docs/quick-start#configuration-file-structure) as part of a single ORM config. If you want to use such a combined config file, you need to destructure the result, since it will be also an array:\n\n```typescript\n@Module({\n  imports: [\n    // `config` exports an array of configs\n    ...MikroOrmModule.forRoot(config),\n    MikroOrmModule.forMiddleware()\n  ],\n  controllers: [AppController],\n  providers: [AppService],\n})\nexport class AppModule {}\n```\n\nTo access different `MikroORM`/`EntityManager` connections you have to use the new injection tokens `@InjectMikroORM()`/`@InjectEntityManager()` where you are required to pass the `contextName` in:\n\n```ts\n@Injectable()\nexport class MyService {\n\n  constructor(@InjectMikroORM('db1') private readonly orm1: MikroORM,\n              @InjectMikroORM('db2') private readonly orm2: MikroORM,\n              @InjectEntityManager('db1') private readonly em1: EntityManager,\n              @InjectEntityManager('db2') private readonly em2: EntityManager) { }\n\n}\n```\n\nWhen defining your repositories with `forFeature()` method you will need to set which `contextName` you want it registered against:\n\n```typescript\n// photo.module.ts\n\n@Module({\n  imports: [MikroOrmModule.forFeature([Photo], 'db1')],\n  providers: [PhotoService],\n  controllers: [PhotoController],\n})\nexport class PhotoModule {}\n```\n\nWhen using the `@InjectRepository` decorator you will also need to pass the `contextName` you want to get it from:\n\n```typescript\n@Injectable()\nexport class PhotoService {\n  constructor(\n    @InjectRepository(Photo, 'db1')\n    private readonly photoRepository: EntityRepository\u003cPhoto\u003e\n  ) {}\n\n  // ...\n\n}\n```\n\nYou can use the `@InjectMikroORMs` decorator to get all registered MikroORM instances:\n\n```typescript\n@Injectable()\nexport class MyService {\n\n  constructor(@InjectMikroORMs() private readonly orms: MikroORM[]) { }\n\n}\n```\n\n## Testing\n\nThe `nestjs-mikro-orm` package exposes `getRepositoryToken()` function that returns prepared token based on a given entity to allow mocking the repository.\n\n```typescript\n@Module({\n  providers: [\n    PhotoService,\n    {\n      provide: getRepositoryToken(Photo),\n      useValue: mockedRepository,\n    },\n  ],\n})\nexport class PhotoModule {}\n```\n\n## 🤝 Contributing\n\nContributions, issues and feature requests are welcome. Please read \n[CONTRIBUTING.md](CONTRIBUTING.md) \nfor details on the process for submitting pull requests to us.\n\n## Authors\n\n👤 **Dario Mancuso**\n\n- Github: [@dario1985](https://github.com/dario1985)\n\n👤 **Martin Adámek**\n\n- Twitter: [@B4nan](https://twitter.com/B4nan)\n- Github: [@b4nan](https://github.com/b4nan)\n\nSee also the list of contributors who [participated](https://github.com/mikro-orm/nestjs/contributors) in this project.\n\n## Show Your Support\n\nPlease ⭐️ this repository if this project helped you!\n\n## 📝 License\n\nCopyright © 2018 [Martin Adámek](https://github.com/b4nan).\n\nThis project is licensed under the MIT License - see the [LICENSE file](LICENSE) for details.\n","funding_links":["https://github.com/sponsors/B4nan","https://paypal.me/mikroorm"],"categories":["Integrations"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmikro-orm%2Fnestjs","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmikro-orm%2Fnestjs","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmikro-orm%2Fnestjs/lists"}